- When you are ready to really sit down
and build a production level project,
Package Oriented Design is gonna be your friend.
You really, I really want you to spend some time
reading those links that I have on this page.
Because they go into a lot of detail about what I'm
going to cover.
But Package Oriented Design is really important.
'Cause what it's going to do is,
is give you and engineering decision
about where packages go
and it's going to help you identify how your Go project
should be structured.
And it's going to really improve communication
between you and your team members.
The whole idea here is that we want clean
package design and project architecture
that is not random but
very predictable.
The whole idea around mental models
is knowing where everything is.
And if you don't have a Package Oriented Design
around your project structure and your packages,
you're really going to have lots of problems.
Maybe not today, maybe not a month from now,
but you will definitely years.
And also depending what kind of turnover you have.
What's interesting to me is the history behind packaging.
There was an interview given to Brian Kernighan,
in the year 2000.
And Brian was asked this question,
can you tell us about the worse features
of C, the C programming language, from your point of view?
Remember, this was 18 years ago
And this was Brian's response,
and when I read it for the first time,
I almost fell out of my seat.
I think the real problem with C is that it doesn't
give you enough mechanisms for structuring really
big programs, for creating firewalls in that program,
to keep the pieces apart.
It's not that you can't do this, and it's not that
you can't simulate it.
You know you can simulate it OOP all you want,
you can do that,
but here's the key.
You can simulate it, but the compiler and the language
is not giving you any help.
When I read this for the first time,
I almost fell out of my seat.
I mean, here's Brian saying that we have this language
that we're using, but when programs get too large,
we have big problems around encapsulation
and mental models.
And here it is, Go is saying, you know what, Brian,
you're right, and we're going to fix this
with the concept of packaging.
Packaging is our basic unit of compilation in Go.
And it's how we really structure
and think about applications.
And the promise is very, very different
from Object Oriented Design.
Very different.
And so, all of us, me too for a long time,
struggled with this idea of Package Oriented Design.
So, I want to try and give you some guidelines
and some philosophies so you can, hopefully, start thinking
from an engineering standpoint, how to do this better.
And there isn't just one way to do this,
I want you to understand,
this is the way that I've developed
over the last five years.
This is how I'm doing it.
I am doing it successfully.
But every project's different,
every team is different.
Dynamics are different.
So I don't want you to feel like you're locked in.
What I want to make sure is that you've got project
structures and philosophies that are in line,
and you've got policies
and procedures that are in line with this.
So I don't want to say this is an end all, be all.
And what I'm mostly going to share with you,
some of it is agreed upon by the Go community today.
When we start talking about project structures,
this is all me, these are all my opinions,
my ways of doing it.
Don't have to agree with it, at all.
But I think that you'd want to at least find something
you can agree with,
so you can have consistency
and make sure you're maintaining mental models
of your code base.
So here are the language mechanics behind packaging
as it relates to Go.
Now, the big problem here, that you're going to find,
is packaging directly conflicts with how we've been
taught to organize source code.
You've been taught, just create a folder somewhere
in your project source tree.
Throw some code in there and encapsulate.
You know, different parts of your code.
And that is because projects like your C++,
your C Sharp, your Java languages,
you're really building a monolithic application
as it relates to your source code.
In Go, we don't really have a monolithic application.
In Go, every folder in your source tree,
represents a static library.
I want you to think about this for a second.
If we switch over to a project that I want to share,
which is my service project,
this service project can be found on github
under ardanlabs, Go training service.
So I want you to understand that
github.com, ardanlabs, service,
we're going to use this for some Package Oriented Design.
This is a service project that we're developing
and building training around to teach people
how to write services in Go.
This is what I want people to be learning next,
after this class.
So, what I want you to understand is,
this is a project,
it has a source tree.
We'll talk about these folders,
but every folder here
like this one call mid,
is really going to end up being a static library.
This is really interesting, because what Go is saying
is that we build software based on the idea that we
build these packages, which are APIs,
which are really static libraries.
And the idea of building an application through
the use of static libraries,
is not necessarily unique.
Languages allow us to do this, right?
C allows us to create those A files,
those SO files, C Sharp lets us do the DLLs,
Java has jar files.
This isn't new, right?
And Ruby has gems, right?
This isn't new, but you have a choice whether or not
you want to build this monolithic app or build it
in terms of these components.
In Go, this is not a choice.
You have no choice.
Every folder ends up being a static library
whether you like it or not.
This really puts a constraint on us.
So you can't just create a folder randomly
and put some stuff in it,
because you're really going to hurt yourself.
You have to think about packaging your component level
API design from the very beginning.
What's kind of interesting to me though,
is that this idea of packaging at the source code level,
here our source tree, really makes me think about
almost micro services at our source code.
Where every folder represents it's own unique API,
it's own kind of program boundary.
Just like we would have with micro services.
So we've got to find ways of decoupling
these program boundaries
and contracts these program boundaries so they can interact.
Again, dealing with what change?
So, it's a really interesting brand-new way
to think of adding software development, design,
and architecture.
Now, understand something, that there is no real concept
of sub packages, just because a folder sitting
inside of another folder doesn't meant that this package
is a sub package.
All packages are built and compiled and then laid out.
From the linkers point of view, all packages
are at the same level.
So, we want to leverage the hierarchy
to give us some indications about relationships,
but from the compilers point of view
there are no sub packages,
there are no relationships,
all packages are at the same level.
And we talked already, about exporting
and unexporting.
Exporting being a way of opening up a packages' API
to be public.
And another interesting thing is that,
two packages cannot cross-import each other.
And this is a really important decision.
It's done to, kind of, simplify things
and it helps to, also, to make sure the initialization
is consistent.
If you have two packages importing each other,
which one gets to be initialized first?
That's a very complicated problem.
Especially, consistency over time.
So, it also makes you slow down
and start to think about, the relationships,
or the importer coupling relationships you have
between packages.
So, the language mechanics are kind of few,
but they do put some interesting constraints on how we
define projects, lay out projects, how we code
and architect and design our source code.
It's no more a monolithic application with folders,
it is a project with lots of individual static libraries
that we call packages
that eventually are going to import and be bound together.
And the more decoupling we can think about in this case,
the better and healthier our projects are going to be.