Coding Blocks - Clean Architecture – How to Quantify Component Coupling
Episode Date: January 8, 2018Joe baits Michael, Michael takes the bait, and Allen lets it happen, as Uncle Bob explains how we can quantify the coupling between our components from his latest book, Clean Architecture....
Transcript
Discussion (0)
You're listening to Coding Blocks, episode 72.
Subscribe to us and leave us a review on iTunes, Stitcher, and more using your favorite podcast
app.
And check us out at CodingBlocks.net where you can find shoutouts, examples, discussion,
and more.
Send your feedback, questions, and rants to comments at CodingBlocks.net, follow us on
Twitter at CodingBlocks, or head to www.CodingBlocks.net and find all our social links there at the
top of the page.
With that, I'm Alan Underwood.
I'm Joe Zach.
And I'm Michael Outlaw.
A quick question for all you trailblazing freelancers.
If you could reclaim up to 192 hours a year of your precious time, would you?
Our friends at FreshBooks who make ridiculously easy to use cloud accounting software for freelancers are the architects behind this
question, and for good reason. By simplifying tasks like invoicing, tracking expenses, and getting
paid online, FreshBooks has drastically reduced the time it takes for over 5 million people to
deal with their paperwork. If that's not enough incentive, the FreshBooks platform has been built
from the ground up. They've taken simplicity and speed to an entirely new level
and have added powerful new features.
Oh, and if you're doing the math,
192 hours works out to two working days per month.
When tax time does roll around,
you'll find tidy summaries of your expense reports,
your invoice details, your sales tax summaries,
and a lot more.
If you're a freelancer listening to this
and not using FreshBooks yet, now would be the time to try. FreshBooks is offering a 30-day unrestricted
free trial to our listeners. To claim it, just go to freshbooks.com slash coding and enter coding
blocks in the how did you hear about us section. All right, first up, a little bit of news here.
We're starting with reviews. Alan, you want to tell us about the iTunes reviews?
Yep.
So we've got Dev Material, BT&Ds, and you know who you are.
Brome, CS Olson, and we've got some Mandarin here.
That was fun.
It actually translates to Paul Bear.
I'll plug that in to translate.
That was good.
The Real Mr. Nice, B. Efferman, and Jeremillo Developer.
And on Stitcher, we have Georgio33, Jenna Tulls, Blue Wilson, Daniel Holter, and Jimmy Cliff.
All right.
And on Podchaser, we got RMQuist.
Thank you very much.
Yes, very much indeed.
And so I wanted to give a quick shout out here. So being that we're
all into programming and we like puzzles and things like that, like that's what we do is we
solve puzzles. I've really, my wife and I have gotten into where we really like doing escape
rooms. And if you're ever up in the Kennesaw area, there is a really good one. And this guy,
he's trying to live the dream, right? Like he's done his own business here and created this escape room.
And it's called Mindscape Rooms.
And I highly recommend it.
Like all kinds of cool little electric gadgets.
Like you do something over here and it unlocks something over here.
Like it's just really fun.
They did an excellent job.
So if you're in the Kennesaw area, definitely go check them out.
It was a ton of fun.
Did you escape? Of course we did, man did man come on how many hints did you get uh we use our hints that's no doubt
but but that was it but we did get out it was a lot of fun those can be really hard some of them
are incredibly difficult but it's perfect for puzzle solvers, right? Like it makes your brain work in a different way, which is awesome.
So just a heads up for anyone who's not already taken advantage of this, Pluralsight is giving away for free three months with a Microsoft Dev Essentials account.
So not entirely sure if this is still valid,
but we're going to include the link in the show notes,
and hopefully it'll still be a thing.
This was sent to us by our friend Viv,
who's the co-organizer for SwanseaCon.
Yep.
And DevEssentials comes with a whole slew of its own stuff,
like cloud access, developer tools, all that.
So you get a bunch of other stuff with it.
But having three months is a pretty good way to start your new year out.
Yeah, it's Microsoft Visual Studio Dev Essentials.
So you probably have an account anyway.
And it's really nice.
It's really free.
And three months of Perl site is pretty amazing.
You can watch like 10% of the videos in that time if you really tried.
10%.
They have a ton now.
Yeah, they do.
All right.
And speaking of Perl site, if you decide that you want to sign up for it,
if you and you also want to support the show,
you can go to codingblocks.net slash resources.
And we've got a bunch of affiliate links and just other things that we kind of like there
that we get a lot of questions about.
And if you go to that page, click on some stuff,
you'll be helping support the show
and also be getting, you know, cool stuff that you want anyway.
So check it out.
That's codingblocks.net slash resources.
All right.
Well, this is it.
This is the episode you've been waiting for.
We're talking about component coupling, where Uncle Bob is going to introduce three new principles to us to help us
define stability and abstraction and show us how we can mathematically graph the quality of our code
and finally explain to us how independ works. True that. I don't know about you guys,
but I really enjoyed this particular chapter. Yes. I think you guys will
hear it as we get into it, but this one had a ton of meat in the meat and potato department.
So here we go. The first one we're going to kick off with is in the component coupling is
acyclic dependencies principle. And the first thing that they say here is allow no cycles in
the component dependency graph. And to several of you listening, I'd venture to say a lot of you listening,
you're going to be like, what does that even mean?
The whole cycle in your dependency graph basically means it can't come back to itself, right?
Like there's no point where you can follow the arrows of one thing pointing to another
and it circled back to you.
So that is a circular dependency is what you also call it when
you're talking in programming terms so that's what they're referring to when they say no cycles
in the dependency graph yeah basically draw all your components and with arrows of which components
depend on some another component and keep drawing that one And if you have any path that can circle back on
itself, then you have a cycle. Yep. Yeah. And back on itself isn't necessarily meaning just
pointing to itself. It could be just further up two levels in the chain, right? And then come
back down. Yeah. If you can eventually get back to it. Yep. Now I got to ask the question,
how's this even possible? How can you have a a how can you have a cyclic uh circular
dependency and it compile we've definitely seen it where it compiles i think so i know a c-sharp
will kind of yell at you about stuff like this i was just kind of wondering the same thing um
you know i saw the graphs in the chapter and like you know kind of like made sense but now i actually
think about trying to compile like i don't know how i could reproduce this unless we're talking about total disparate
you know systems well the one thing that i was thinking about it was like interpreted languages
those were the only kind of environments where i was thinking like well okay well maybe because
you're not like pre-compiling you're not like you know um doing things like includes or imports you
know you're just figuring it out at runtime what's necessary.
And I was like, okay, maybe in something like that,
but in any kind of compiled C, C++, C Sharp, Java,
I was a little confused as to how you could get into that scenario.
But yeah, we can go on.
Yeah, I can't think of how you could do it. It seems like I've
seen it. Maybe I'm wrong. Maybe I am thinking like JavaScript or Ruby or something like that.
But yeah, anyways, what they call here is the morning after syndrome, which is interesting.
It's kind of funny. They talk about when you work late one night and you're busting your tail,
you get something working and it was perfect that night. You left at midnight, all is well. You come in the next morning, first thing, you pull in your
latest code and it's not working anymore, right? It's happened. Everybody who's worked on any kind
of teams, this has happened to them at some point. That is the most surefire way to ruin your day.
It is. Because you go go home you stayed late that
night anyways working and whether it was because you had to or you wanted to or whatever the reason
was you by the time you left you're like yes it's working i did it it's done and then you come back
in the morning you're like yeah you got this big smile on your face ear to ear and then you pull
the latest code down and then it doesn't come on you're like what what just happened yeah and a surefire way to get this to happen is to have a
long-running branch like go you know spend a week two weeks working on some big feature and then
you go to merge in and oh the ground has changed underneath you everything is different so now you
can't merge in so now you spend another day you know getting up to date oh but now they don't
want to merge in because you know some other stuff's going along.
There's going to be some sort of release.
It's, you know, it's considered risky now that you've had a couple of conflicts.
So let's push it off another day.
And next thing you know, you're looking at week three.
And it just gets harder and scarier and more difficult as each day passes.
I found this very interesting that he said that this can happen when too many developers are working in the same files or project yep it was almost like not only is the book talking about how to structure and
organize and architect your code but in a statement like that he's also talking about your teams
and the organization of your your your development you, the developers within your company.
How they should work, yeah.
And they also say this makes it extremely difficult
to get a build out,
which is what Joe just referenced, right?
Like, you know, here it is, it's Friday,
you're supposed to be getting something out
and all the stuff that was working Thursday night
is now back into a state of, you know,
probably disarray and maybe
not even testable at that point, if that's the case. Right. So yeah, there's, there's all kinds
of things. And they say there's two, there's two types of solutions that have evolved. And we're
going to talk about the first one now. Yeah. And this was curious too, because he says that both
of them evolved from the telecommunications industry. i didn't have a chance to go back and like dig into where that was but i did find that super curious i want to go back um and try to
remember to look that up but if anyone uh is familiar with where this came its origins within
the telecommunications industry i'd like to know and the first of that was the weekly build. I bet nobody's heard this one before.
Yeah. So basically the idea here is that, you know, because the build was such a hassle
and merging in everybody's code and whatnot, it was just, it was so burdensome that, you know,
that became such a burden that it would take an entire day. So the idea was, well, we'll let all the
developers work for four days and give them four solid days, uninterrupted time. They can just do
their own thing in their own code base, their own repository, whatever, locally do their development.
And then we'll worry about integrating in with everybody else, with everybody else's components
and code and whatnot at the end of the week.
So we'll do that on Friday.
We'll save it for one day out of the week
and we'll figure out the problems then.
Yeah, I haven't seen it weekly,
but I've seen it in kind of like larger projects
where you've got multiple teams.
And so you say like, you say the installer team
is kind of off doing their own thing for a sprint
or some sort of cycle.
And the UI team is doing their own thing.
And they're kind of like either mocking out those dependencies or just kind of ignoring or whatever.
And then you've got some sort of, you know, some other team doing something separate.
And then at some point you kind of try to bring them all together and do some sort of, you know, a big test.
And it's always terrible.
And it's like weeks of terrible.
Like a large percentage of the time you spend developing, terrible.
Yeah. And it doesn't get better. Like they
say here, the problem is that Friday build starts trickling into
Saturday, right? Like, oh, we got to get this build out. So then people
end up, you know, they probably stay all day Friday till 7, 8 o'clock
at night and then they're back in Saturday morning and try and wrap the thing up.
And then eventually that breaks down, right?
And then it starts taking all day Saturday
and starts creeping into Sunday.
And then people will say.
Well, it starts backing up
because you're willing to accept that one Saturday.
Right.
Right.
You're like, oh, fine, whatever.
It's just, it's once in a blue moon, right?
And then there's that second and that third Saturday.
And you're like, whoa, hold on.
I'm seeing a pattern here.
Right. We got to start this process on thursday so now all you developers you get three solid days
and we're going to take two days to do the build and so it like expanded out like i kind of talked
about where it was like okay now we do the first three weeks is development and one week is
integration or two weeks development two weeks integration or you can kind of set that dial a
bit more granular but both are it's just crazy yeah it's ridiculous because then your
productivity takes a major hit right like you're not developing you're not creating stuff now
you're just dealing with with garbage that has to all flow together at the end
yeah the bigger it gets the worse it gets yeah and i was curious though too and and maybe this
is where the telecommunications part came from but like i've never worked in an environment
where we only did a build once a week have you guys i mean i know joe you already said you haven't
alan no i would i mean um so not necessarily a bill but kind of um those those like milestone kind of releases like where
everyone the teams go work for three
weeks or four weeks and put the stuff together
then kind of kick over a version to QA
I've definitely worked in that environment
that's what he meant
that's what I meant but we did have
nightly builds in that place and that was just more to
kind of keep your stuff kind of fresh and
integrate with those changes but like we never really tested
things all together until these bigger milestones that's because so much stuff
was changing and it was too hard to try and adapt to those changes and things that you were even
testing and working on sometimes like in my case was like backup and restores so they could even
take hours to test you know for real so most of our work was done you know kind of trying to figure
out how to make shorter feedback cycles so we can do our testing and mocking.
Then you throw it all together and give it to QA once a month or whatever and then they
shoot holes in you.
Maybe we should rephrase this. Maybe he's not necessarily referring to the
weekly build as in, hey, let's compile this thing. Maybe he's really
meaning the weekly delivery as in like, hey, let's compile this thing. Maybe he's really meaning like the weekly delivery.
I think it could be both, right?
It could definitely, yeah.
I mean, because it could be that your code didn't integrate well with my code or whatever,
but then it could also be, does this thing work?
Right?
So I think both are legitimate problems that occur with this.
Yeah.
I mean,
he says that this is eventually going to lead into a crisis though,
because going back to the schedule,
the build schedule lengthening over time,
you know,
where if it creeps from Friday back to Thursday,
or,
you know,
as Joe said from,
you know,
an entire week to,
you know,
two entire weeks to do that, you know, you're going to get into a crisis.
Yeah, you know, my example, we were definitely building every night and that was a pain in the butt.
But at least it didn't mean that we didn't have to have some big integration day where we just kind of fixed all the build servers.
So I think, yeah, I can't really think of a good example where someone would be working in their own silo for a week or two weeks and then trying to all merge on the same day.
That seems pretty crazy to me, but maybe that's old school or maybe that's just a type of product that I've never worked on.
Yeah, I'm definitely way more familiar with nightlies being the norm. Yeah, you ever do something like you check something in at like 5pm and it works great
and somebody manages to get something else in
or somebody checks something in at like 4.59
that breaks you and you didn't even know it.
I've seen a build server and it finally gets to it
at like 11 o'clock at night and
pulls the and-on cord and stops
the train and you're in trouble.
So then that brings us
into the second one, which
is removing dependency cycles. Yep. So then that brings us into the second one, which is...
Removing dependency cycles.
And so our first approach was basically just having a kind of a weekly build
that brought everything together.
Now, removing the dependency cycles is kind of taking a different approach.
It's saying, hey, let's not have dependencies on each other's code.
And so the developers will work on independent releasable components.
And did we talk about what components were to be defined components?
That's kind of loose.
I mean, you want to give it a stab?
Yeah, I think we talked about it last time.
I just can't remember.
We brought it up last night.
But it's basically the smallest releasable component.
So there you go.
Recursive definition.
Let's call it the unit of work.
Smallest releasable unit of work.
There we go.
Deliverable.
All right.
Yeah.
So we have like, I don't want to say microservices because that's an example of having smaller
releasable components.
But the idea of just breaking something into smaller releasable chunks so that, you know, say Outlaw can work on the server, Allen owns the database, I've got the UI.
And then each one of those is independently releasable and can actually potentially work with older versions of its dependencies in order to kind of keep things moving and working.
Well, heck, even if we took it into the level of, let's say, JavaScript,
like NPM, that would be a component, right?
Or it could be a very small component.
It could be a massive component.
Well, you could have multiple components that are delivered by NPM.
Same thing with NuGet and C Sharp.
In Java, you could have jars and various different things.
So, yeah, I mean, it could be anything that you're going to release out to another group to use.
Yeah.
And what this allows for, though, is it allows you to have more integrations more often, but they're smaller.
And because of that, they're more manageable.
Yeah, and also uh well i was gonna say like uh i think like one of the examples we talked about last time for components was
um one of you guys wrote some amazing logging component i think it might have been alan so like
you know alan releases his new uh the latest version of his login component and now i want to use it and maybe there's some
change to it or maybe there's just a new feature that i want to use so when i bring in that latest
version yeah i don't have to bring it in until i'm ready to do that integration and take advantage
of that feature or make whatever the necessary change is for it. So it allows you to schedule those a little bit easier.
Yeah, and this gets back into what we talked about in the last episode
with the semantic versioning.
So when you complete these components, you actually version them
so that other teams know you're communicating to them,
hey, this one is backwards compatible.
You know, we talked about the second digit being the second digit being additional features being added or whatever.
The third digit being bug fixes, that kind of thing. So you can actually
communicate through your release number of whatever component you're creating so that
these teams know whether or not, hey, we need to pull this in because it's fixing a bug
or I'm getting new features or whatever.
And that was the reuse slash release equivalence program,
sorry, principle or the REP.
Episode 71.
Yep.
And here's the thing, right?
The whole purpose of this thing is,
is when teams are depending on just components
that are being released from other teams,
then you don't
have this whole need to do this weekly build to throw things together because they're all
independently being tested you know and you hope it would it should be right otherwise everybody's
going to get a pretty bad setup but but that's the whole goal is these things are being created
i hate to say it this way but sort of in a silo.
So they're more hardened.
And so when they get released out to the other teams, then they just get plugged in, right?
It's just a piece that gets added to it.
Okay, so how about this?
Let's pretend I have a big project and it's only one project.
It's only one component.
So it's one big, releasable, monolithic application.
And I still have a lot of different people on it.
So now people might be working on, say, different namespaces or different files.
And then it's really easy to have cross dependencies and not even realize that namespace A depends on namespace B and namespace B depends on namespace A.
Because that's not a compiler problem.
That will compile just fine, I think.
But we should try that.
But it's much easier to make those kind of mistakes.
And so I think this is also kind of a good argument for kind of having those nicely kind of cleanly defined components, which we talked about last episode as well.
Yeah, I mean, problems like this are interesting.
I've talked about it with several people that I work with, including Mike,
is like, you know,
what you were talking about is you have one huge project that has a ton of
things in it. Right. And like you said,
those things all sort of work together and we'll get further into this a little
bit later in this chapter here.
But I think the answer is, is you start pulling those things out, right?
The things that should work independently, that shouldn't be a part of this whole dependency
thing, right?
Like we've even talked about in the past, right?
Don't make an object rely on an interface that has so much that it doesn't need, right?
It should be the bare minimum of what it needs.
So you start pulling those things out into their own components
and so that they can be broken out.
And now you have these things that are sitting by themselves, right?
That you could potentially version and do all those things too.
I think that's probably the way to go with things like this.
Yeah.
And last time
we talked about the common closure principle and the common reuse principles, ways to kind of know
like just when to break things up. And so it's not too small and annoying and it's not too,
too big and annoying. But if I just wish there was a way that we could like, I don't know,
statically look at our project and maybe do a little math and come up with a number that tells us whether
we've got too much stuff that's uh too interrelated or too big too concrete or too abstract hmm if
only there was a way if only hey by the way you mentioned uh the project uh the namespace
depending on namespace depending on you know namespace a depending on namespace b depending
on namespace a right but if they're all in on namespace B, depending on namespace A.
Right.
But if they're all in the same project, the namespaces are just an organization tool.
So it shouldn't be a competition.
Yeah, that's my understanding.
So I wasn't sure if that was actually a problem.
I know an independent will yell at me when I do that.
Yeah.
So I guess there's the answer.
Like you can do that and you shouldn't do that.
And static analysis will catch it for you.
Because it's basically a folder more or less.
Right.
Yeah. Yeah. And it doesn't a folder, more or less, right? Yeah.
Yeah.
And it doesn't even have to be in C Sharp.
You can kind of name those things whatever you want.
Yep.
Yeah.
But even Visual Studio will yell at you about that, I believe.
ReSharper will.
Yeah.
So if only there was a way, right?
And this is where we talk about this whole, we need to remove the cycles.
And so the graph that we were talking about where you have arrows pointing for your dependencies,
your top level dependency pointing to your next level dependency, that's called a directed acyclic graph.
And the whole goal is with those arrows pointing down from one thing, depending on the other
to another, that should never circle back up to any level up above it.
They could come back to it somehow, right?
And that's what they talk about.
You need to make sure there are no cycles.
So that's what you're doing when you're removing these cycles.
Yeah, I will say, though, that every time I kept looking at that,
I kept reading it wrong and be like, oh, well, this depends on that.
Oh, wait, I got the arrow wrong.
Yeah, I have a hard time with those arrows.
It's really kind of silly.
I do like how independent graphs, I talk about independent a lot because it's like the only static analysis tool I've got experience with.
But it's kind of silly.
But it actually, the way it kind of draws the thickness and draws the arrows, it kind of makes them more curvy.
There's something about that curve that kind of like makes me understand it a little bit better you know about the straight lines and seeing
them just like it makes it hard to tell which direction is moving you know i think there was
another one that was mentioned previously was a sonar cube yeah so that's that's another one of
the static analysis uh tools out there that people use quite a bit um anyways so one of the static analysis tools out there that people use quite a bit.
Anyways, so one of the questions we have, is this advocating for breaking the teams by source code
or by feature? Yeah, this
is going back to that other point about where it's like not only how
do you organize your application, your software,
how do you organize your developers? This software how do you organize your developers
this one's so hard i mean i i think it depends on projects and i get frustrated by this one because
i don't really know a right answer so let's take for instance let's say a website right a website
a lot of times you don't the ui is like this one thing, right? And while it may all somewhat tie together,
it's not like you were in most cases and not most cases I've seen. It's not like you bundle up
pieces of your website, right? Like you don't have this page has these components over here.
And then you, you version that page where you version those pieces on that page. And then you
have this page over here that has other ones and you version those pieces on that page. And then you have this page over here that has other ones
and you version those pieces on the page.
And then you've got things like routing, right?
That is cross-cutting across the entire app.
And this is where I get, I have a hard time,
like for whatever reason,
when I'm thinking about middle tier code,
like server side or even database code,
it's easy for me to compartmentalize those
things but when it comes to ui pieces this is where i struggle with how that happens
and what's the answer do you break it apart to where you have multiple teams that are just
they work on one page it seems like the book kind of assumes that you're broken up almost by
component so that people working component a don't know
about what's going on in component b and like that's kind of a point of the abstraction there
so i kind of feel like there's some bias for that there but what about like a website with like
routing though well another way to say that component would be feature right so going back
to you know you you could break it up by feature. A component is a feature.
Logging is a feature, going back to logging as the example.
Right, and that one's easy for me, right?
Like I said, when it comes to UI pieces, this is where I get really frustrated when trying to figure out how to split those things properly because you have things. Well, even in your web example, though, you could have components within that web example and each of those web components would be responsible for their own routing.
Going back to your routing question, right? But you have these pages that hold these components,
right? So you have a page and it has five components on the page. So those components
are completely independent of the routes, at least from a high-level view of that page.
You know what I'm saying?
And that's where it's hard because routing is like its own beast.
That's a page-by-page thing.
You can pull in as many components as you want.
If you wanted 20 components on that page, you can bring them in.
And all those components have state that is typically pulled in by whatever
the url is and so now how do you break that thing up does somebody own routing for the entire website
and that's the component but that component has to be aware of all the other components on the
page because it's what hydrates i don't think you could do that i don't think that would be
and that's that's the part where like talking about certain parts of
applications this stuff really makes sense to me but other parts of it like that where there's
things that literally are so intertwined with the other pieces that really drive me crazy like
because if they're intertwined then they should be deployed together right and you know ideally
is in the common enclosure principle,
according, you know,
if we were in a perfect world,
then things that change together would stay together.
So if the routing is entwined
with the website,
then the website would be
its own component.
So we're saying the website,
it's just one component.
You don't break it up into pieces.
So either you need to figure out
how to break it apart
with some sort of like
modular interface,
you know, somehow somehow and have those
be separately releasable components
or you just you know have it
be one big fat component
that's such a hard one
you still have modules you know you have just like you have
namespaces in a DLL or something it just
you know that stuff is really
so entwined that every time you're changing a route
you're changing the website too
then why
separate them interesting i was trying to think of an example like um you know we've talked about
elassian before so you know like jira would be one component confluence would be another component
yep right but even those are like whole apps though right like and that's that's where i feel Confluence would be another component. Yep. Right?
Those are like whole apps though, right?
And that's where I feel like components stretching it.
That's not a component.
Like a component.
What about this one?
What about this one? What about Office 365 on the web, right?
And within Office 365, there's Outlook, there's Word, and there's Excel.
Those could be different dev teams.
Those are apps, though.
I'd say even within those teams, right?
There's going to be components.
But there's still the container around that.
Right.
There's the Office 365 container around it.
Right.
Right?
Yeah, I think this is where it's hard to draw the line between a component and a full-featured app, right?
Because that's where I wouldn't be surprised. Like, for instance, Office 365 is a great example, or even Atlassian.
They're going to have a logon component that all of them use, right?
Like all of these things are going to have some sort of token that says, I have access to products A, B, C, and D.
So that is a component that whole authorization
authentication piece is a component that they all share. And then there might even be additional
things like a perfect example now is cloud storage, right? If you want to save an Excel file online,
you can say, hey, save it to my OneDrive or save it to whatever. And that's a component that they
all share. But then when you start looking at something
like Excel, there's tons of different components
within it or even Word. And that's where
I'm like, how do you break
that apart? I mean, even if we were to talk
about another app, even if we were to break this out into
another application like a Spotify, for example,
there might be one component
that's just the ads that are going to
be served, right? And deciding what
ads to show you. There might be another component that would just the ads that are going to be served, right? And deciding what ads to show
you. There might be another component that would be search, right? But those aren't components,
right? Because those are, unless they're an actual separate service, like you would deploy
the search service or the ad service, and all of that is kind of transparent to the user because
they're just going through their app, which I would consider that another component. So the
whole app, I would say, is one component. Well, I was thinking of the app as comprising of multiple components within it.
A container of components.
Yeah, it's a container of components.
But you can't deploy one of those individually.
You deploy an app version.
The app version is an aggregate of some selection
of components but what version of those components you decided to include in that version you could
change now once you've made that installer and it's out there you know you're done until but
even in a uh you know an update capability where you where your application can update itself,
you might update selective components.
Yeah, I like the Spotify example because I think there are a ton of features
in Spotify that you can absolutely identify as separate components.
Search would be one.
That could totally be a service.
Totally.
But you can't deploy just the search.
It could be like its own DLL.
Why can't it be its own?
It's its own DLL, but you still, I would say the actual, so the DLL maybe is its own component.
But when you're talking about the app, I would say the whole app is a component.
No, no.
And that's, I think, where we've got to sort of draw this line or differentiate what an app and a component is.
So what you're talking about is you can't deploy that UI without the search in it, right? That's what you're
talking about. That's an application. That's a compilation of all the UI pieces that tie all
those components together, right? So that search box that's in that UI is using a search component
that has probably been built that allows them to be able to search
whatever their databases are. I'll give you another one like the share, like play on my device or play
on, play on my receiver or play on my iPad or play on whatever. That's probably another component
that they've built that works on their mobile app, on their web player, on, on whatever else is there.
And, and so I think those are the components you're talking
about the entire application you're correct that that app can't be deployed without those components
but i wouldn't call the application a component i don't think because it's not used as a component
it's an end user it's an aggregate yeah which is so now circling back to your web example, that web app is an aggregate.
It is.
And that's what's hard.
Like, how do you, so like I said, I can see how you can break down components, like functional pieces I get.
When you start talking about UI pieces and how all those things tie together, and I'm
not as familiar with Windows programming or desktop type programming applications, but I'm sure the
same type problems exist there, right? Where you have to share state between various different
places. That's where it feels like it's a lot harder to break things out so that the problem
that we mentioned earlier, where you don't have too many people working on code, that's going to
step on each other's toes. That's the part that frustrates me because I can't figure out, or I haven't at least thought of a good way to where you can split that up and say,
okay, you own this piece over here and somehow it's just going to work with this piece over here.
You know, honestly, I mean, you mentioned managing state and I don't know why in reading this
chapter, but for some reason I had this thought that came up, which was that, you know, managing state, it's got to be like the hardest thing that we do in our job.
Second to deciding what to name something like that's that's up there.
That's way number one.
And then managing the state is like it's a distant second, but it is second.
Yeah.
Yeah.
State's difficult.
I'd say caching
also i mean we've talked about like all those type things where you're having to either rehydrate a
portion of an application or or you know save that portion of the application so it can be brought up
like that stuff is so freaking hard well caching is a form of state management right so it is yeah
just a speedier one so yeah anyways i i mean i, I mean, I didn't want to go on that too long, but it is one of those things to where some of this stuff isn't just cut and dry, right?
Like what we're talking about right now, it's easy to compartmentalize some of this stuff.
And other pieces of it are just really hard.
They're really hard to break down in any kind of not meaningful way, but in a way to where you're actually making teams to where they can work efficiently together.
So coming back then to the dependency cycles, we know that having these cycles make the code, well, for one, we're not sure how we could actually have these and the code compiled. But assuming that we do, and we're working in a compiled language,
then it would make the releases difficult and fragile
and likely lead to the morning after syndrome.
So how do we break the cycle?
Yeah, one way is a dependency inversion principle.
So basically using strong interfaces for the
different components and kind of having those contracts or act as a buffer between the
components so you're not depending on component a from component b now you're component you're
depending on interface a which component a just happens to implement. And so you've got a little bit of buffer there.
Yeah, I really like this because in one of them,
they talk about, you know,
you've got this strong dependency from A to B,
like you said, right?
And how do you break that?
So the interface that he was talking about is
you might create a project
that's nothing more than an interface, right?
And let's call that interface project.
So now A is going to depend on interface project
and B depends on interface project.
So now there's no longer a line from A to B.
They're both pointing to that interface project.
So am I alone here then that in this portion,
it seemed like it was understood
that dependency injection is used.
That's pretty much it.
Yeah.
Because he never describes,
he described,
you know,
using dependency inversion to,
to invert the direction of the dependency with the interface,
but he never described,
okay,
well,
how does the thing that's needs to use the interface?
How does it ultimately like what,
what method or
class like how is it getting the actual instance of that other object and the only way that i could
come up with was dependency injection i'd say that's probably the most common i i don't know
if you could but you can manually like you basically have some sort of main method of
some sort of bindings to find somewhere.
You have some sort of factory somewhere that kind of,
you know,
kind of somewhat crappily encapsulates that dependency.
Okay.
So you have somewhere along the line,
there has to be a,
but in a separate project or in a separate,
yes,
it would be a separate thing that would bring those together.
Right.
It's that's what I'm saying.
That was never,
that was never part of his diagram.
Yeah.
Yeah. Yeah.
You could do it.
The dependency injection thing would be a nice configurable way to do it.
Whereas if you went the factory pattern or something like that,
you'd probably have to put that in a new project that they both depend on.
Right.
And then that way you could create those things.
But you see where I'm going with this, though,
because he took the time to draw out a new project
that contained only the interface,
but not the other project that you're suggesting
that would have the factory that would include all of that,
that then you don't need the dependency on that project
that contained just the interface.
You actually only need the dependency on the project
that would create the... Well,, you actually only need the dependency on the project
that would create the, well, I guess you would need that.
No, because the interface project will come along for the ride, right?
Yeah.
So, yeah, it was still weird.
So the only, yeah, I'm pretty sure he was assuming dependency injection.
It's kind of an interesting omission.
Yeah.
And so, you know, one simple example here could be like if i've got code that
currently depends on a database project i could instead swap that out with say like a interface
for data provider um some sort of data provider module and it just so happens that you only have
the database but you've severed that um official line so now um you only have to worry about
updating your say server code when the
interface changes and everything that happens behind that interface is is guaranteed to just
or it's supposed to just work you shouldn't have to be aware of anything
yeah so i'm doing this oh sorry i was gonna say doing this enables us to know how to build the
application because
we understand the dependencies and it just draws some you know clean little boxes around our stuff
yeah we know the order of what what things need to be built first um there was hey this was kind
of funny um and and you know maybe i was just a little dumb when i read this part
did you there so he was talking about how
when you have the cycles,
unit testing and releasing are difficult.
It's difficult to isolate the components
and that the build issues grow geometrically
with the number of modules, right?
Now, here's the question where maybe maybe uh i'm showing my own ignorance i did you had
you ever heard of geometric growth before that statement i picture a polygon growing
i think you meant logarithmic or so i've heard i've heard things in regards to meant logarithmic. So I've heard things in regards to linear, logarithmic, exponential.
I had never heard of geometric growth.
So I had to search for it because I'm like, what is geometric growth?
And so I came up with this one definition I liked.
It was geometric growth rate is applicable to compound growth over discrete periods, such as a payment and reinvestment of interest or dividends.
So it's building back on itself.
Yeah.
That's geometric growth.
Yeah, the definition from OECD, never heard of it.
It's a constant ratio.
So yeah.
Yeah, that's the one.
Scroll down to the middle paragraph.
I didn't actually go to the page.
I was looking at the,
Oh yeah.
Yeah.
But that was,
that was the one that I liked though.
Um,
and,
and I like the example of the payment and reinvestment of interest.
It was like,
okay,
I get where he's going.
I understand now where he's talking about like the,
as you add in the next component,
right.
It's,
it's compounding on itself, making it.
But yeah, that was a weird, I'd never heard of that term before.
All right.
Sorry.
Moving on.
Coolness.
All right.
That's pretty specific.
What's the next piece?
All right.
So the next one that we talk about here is top-down design. And basically, the whole purpose of this section
is to say that you can't design something perfectly
from the beginning
because there's no way for you to see this code
and see these dependencies from the very get-go.
The whole purpose of building software is,
the way he calls it,
is the component structures jitters as they grow,
right? Which is, which kind of makes sense, right? Like as you get in there, you're like,
oh, wait a second, that changed a little bit, or this requirement's not what we thought it was.
And so these things are shifting around on you. So to try and spend just a crazy amount of time
up front, trying to get the perfect architecture and perfect design to get those acyclic dependency graphs set up properly is not the way to do it, right?
Yeah, he describes it really well in this section where he's saying that this diagram,
the component dependency diagram, this is a map to the buildability and maintainability
of the application. And so you can't build the map,
you can't create a map of the buildability of it
until you have something that you can build.
And then once you have something that you can build
and you can build that map,
then you can decide, oh, I don't like the map.
I need to make these adjustments
to get rid of cycles
and things like that. I think that's so important, though, like what you said with the buildability
and the maintainability of the application. All of this that we're talking about in this chapter
has nothing to do with the quality of code, has nothing to do with, you know, did you do your
classes the proper way? It's all about how do
you grow the application in a way that's not going to drive you crazy or introduce just tons of build
problems. This is all about how do you make it to where this thing can grow and still be maintained
over time in a component way, not at the low level class code way, at the component way. Now,
we will talk about code ways to make that possible,
but it is interesting that that is the call-out.
Yeah, the most common theme of any software craftsmanship book
that you'll ever read is going to be that you got to just iterate.
Yep, yep.
Don't ever think that you can do it all in one shot.
Yeah, when we say it talks about the buildability and not the functionality,
it's like you kind of, if you think about that simple example,
you have a website that has like UI, a server and a database,
and maybe we'll say a logging framework.
Someone says, okay, so how do return, you know, refunds work?
And you're like, oh, well, you start with the UI and the server server and the database and there's a lot of logging
mixed in there it's like okay so what the heck it just doesn't really make sense for that so
this was just about the buildability
all right oh so what parts of the application then are the most volatile that one we haven't really
talked about volatile but it basically just means what changes the most and so um as far as ability
build abilities buildability i've always heard that the ui is like the most expensive code because
it's rewritten so often i don't know if that's actually true or not. The book mentions the database being particularly volatile because changes
happen a lot to it. Well, pretty much anytime you're adding
any sort of new concept or anything, you're adding columns or tables or whatever.
Yeah, I would probably
we have business rules here with a question mark. I'd say that's probably once you lock
those things down, those probably don't change a ton, at least for your main use cases, right?
I would say the UI is probably the one that feels like, because it's the most affected by whims or new designs or, hey, we want to try this.
We want to split test something.
We want to do whatever, right?
Like it's the thing that people, that they interact with.
And so it's the one that people want to tweak the most.
Well, I do feel like business rules kind of change
just because we never get them right.
Like if we ever got them right, it would probably be different.
But, you know, you can use examples.
Like we say, no returns after 30 days.
Unless a customer service agent says so oh but now
you know so there's one change and say well that customer service person is having too often now
we need accounting approval so you know we do that so now accounting is eating too much so now
accounting needs to only approve things more than 500 it's like okay that's this is obviously
changing a lot and that's you know just one very small example but i do think that there is some
flex and business rules there even if it's just minor like changing you know from four to a
five or whatever yeah yeah i agree that you're probably going to see the most change on the ui
because that's where your your customers are going to be so you're going to keep
the attraction high you don't want it to be stale um so you're going to want to keep that up but one that you guys
maybe haven't considered is what about non-functionals
right like changes to uh what you're logging or how you're logging or um well we got to make this
change because we want this to process faster or we want to split up the architecture so that we can uh deploy independently
oh god we went too far to microservices it's time to bring that back nobody ever that's a good point
yeah i agree yes after reading this book i did a little uh kind of holiday project
i did a game and the first thing i tried to do is like okay i'm gonna think like architect let
me draw some boxes and i started trying to kind of draw stuff but what i ran into
really quickly is like i don't know what i'm doing i don't know you know i don't know what
kind of game i'm making i'm making a bunch of assumptions so it didn't really make much sense
for me to draw anything plus i was i was doing just what the book says is not a good idea where
i was like drawing components like here's my graphics layer and here's my data storage
whatever i'm trying to figure out like how the gameplay works from that it just wasn't happening you were trying to draw a map before
you had anything to build yeah and i wasn't even drawing the right things you know like let me draw
a map okay uh here's some blue red i have a little green over yeah all right start navigation that's working right code
good enough so uh so one thing i thought was cool is like we talked about this this component
diagram and dependencies and the buildability um who makes that diagram when do they make it
according to uncle bob it would be the architects
our case is like a monday morning like we all draw our component diagram well when does this
happen this is this is uh i don't know if you're if you're baiting me but i'm gonna take it so
he says that uh this is a quote from the book the component dependency graph is created and molded by architects to protect
stable, high value components from volatile components. Okay, so maybe this is the kind
of case where someone would say, you know what, the developers are going a little crazy. They're
complaining that the code is hard to work with. Let's draw our components up here and see if we
can figure out where some of our trouble spots might be and what to do about it. Yeah, probably. And I'd venture to say that you'd probably use tools like, you know,
the Visual Studio analysis thing to show you where your dependencies are or independent or,
you know, any number of other things to assist with that, right? And I feel like we're going
to talk a little bit about how we can quantify some of this stuff here in just a little bit.
But maybe going back to part of Joe's question, though, about like, well, is that a Monday
morning thing or whatever?
Maybe some static analysis tools in your build pipeline.
Totally.
Because they can even spit out the reports and you can have thresholds set up to alert
you of some of these things, right?
Or if nothing else, just to keep it up to date so that when you do
want to see it at a minimum, at least it's already there, right? Yep. A release is taking longer than
anticipated. Why is that? Let me go look at our dependency graph and see what's going on.
Yeah, that's a good way to kind of get this kind of conversation started. If you're working with
somewhere and you're feeling some of the pain about the code and management's tired of hearing
you complain about the code, they're not really taking it seriously maybe you can say you know
what let's throw some static analysis on here so we could just kind of graph things and see
that you know just make sure that we're going in the right direction that's something measurable
that's something management would normally like and you can do it really cheaply sometimes sometimes
you know maybe even free so it's something to consider to get that conversation going it's been
a long time since we've talked about static analysis.
I think it's worth saying the whole reason it's called static analysis is because it's analyzing the code after it's built or it's analyzing the state of the code.
It's not analyzing it running.
It's not any of that.
It's just looking at dependencies and how things are connected and all that kind of
stuff.
So it's worth knowing that when we talk about static analysis tools,
it's literally just looking at how your code is set up and connecting the dots
between everything.
And I've never seen static analysis tool that will like call out individuals.
You don't have to be to worry about like campaigning for getting the static
analysis into the pipeline and then having the first report come back.
Like Joe's code stinks the most.
Well,
that's why I like to make all my namespaces like that.
Joe's code.
That's right.
All right.
So let's take a little break and talk about how much we love reviews.
And we actually set up a URL,
so you can go to codingblocks.net slash review,
and we have links there to iTunes, Stitcher, Podchaser,
anywhere else that you might be able to leave a review.
And we know that iTunes is a pain in the butt if you don't run it,
but a lot of times you can even do that stuff in the apps there.
So we love that stuff.
The reviews are really huge for us finding new
listeners and kind of surviving and competing with other podcasts so we love those reviews we get
fantastic ones we love reading them and so if you've got a few minutes please hook us up And with that, we head into my favorite portion.
Survey says.
All right.
So last episode, we asked how many developers are at your company and your choices are just me.
About five, like Captain Planet.
Or closer to the 20 mark.
Headphones are required. Or crazy right or thousand plus enterprise all right let's go with joe first i'm gonna say um about five about 30 five at 30 yeah i know anecdotally we don't hear a lot from people
working at really large companies like you would think you know microsoft has like 80 bazillion
developers that you know just based on those numbers alone you'd see a lot of activity from
those but i think a lot of those bigger companies kind of have a closed ecosystem. So there's not a lot of kind of people necessarily speaking out or
kind of living out in the greater dev world if they work at one of these large companies. So I'm
going to go small. Yeah, you know, I'm kind of thinking along the same lines, just because
I feel like a lot of people that hunt out podcasts or learning things are because they're not immersed as much
in it and they just
thirst for it.
And so I'm thinking smaller as well. I don't
want to pick the same one you did. So I'm going to say closer
to 20 and I'll
go with...
I'll say 30% on that one also.
Okay.
Survey says... We're both wrong no joe nailed it awesome it was uh about five thirty percent
really was the top top choice on the money yep he hit it on the money cheater
what do i win? Yeah.
So that was very interesting. And I guess it kind
of makes sense, though, because most businesses
out there aren't
dev shops.
Right? So, you know,
it might make sense that most companies
that might want devs wouldn't
just from a numbers game,
right? There would be more that wouldn't have a large
team.
What was the second one?
You had the second.
Okay.
Yeah.
So it is a bunch of smaller shops.
But it was 20%. Okay.
Yeah.
So that was 50% of the overall makeup.
It fell off after that, yeah.
What was the next one, five?
Well, 100 and Enterprise were both at around 19%.
Well, that's kind of cool.
That means that there are people that are working in larger companies that are still trying to improve their craft.
I love that.
That's awesome.
Yeah.
Yeah, we know some of them from the tech group, but it definitely seems like the vast majority are smaller shops.
Yep.
Excellent.
Oh, yeah, we should.
All right.
We should what, Alan?
We forgot the mission.
We always forget about this until after the fact.
So we're talking about clean architecture, and we love to give things away.
So be one of the people that leaves a comment on this episode with some of your thoughts about what we're talking about here.
And, you know, you'll be entered for a chance to win a copy of clean architecture by robert c martin and if you're looking for an idea as to
what you might write about on the comment let me give you an idea so today's survey we're going to
ask how often do you shut down your computer and this was sent in from the Slack channel, and I forgot the names.
It's either Swix or Dance to Die, but I don't know which one.
I think it was both.
It was a combination of the two in a conversation.
New York City represent.
Yep.
How often do you shut down your computer?
And your choices are shut down daily.
Nobody does that.
Every week, every month, or only when the updates force me
to or who shuts down their computer or i don't shut down often but when i do it's because it
blue screened or colonel panic what about uh adding another one because I'm a pain in the butt for vacations only?
Hmm.
Hmm.
Sure.
Okay, so PTO?
Maybe one for weekends.
Oh, it doesn't have to be paid.
It could just be time off.
Just T-O.
T-O.
That's right.
Vacay.
There it is. There you go. That's right. Vacay. There it is.
There you go.
Yeah, I shut down daily.
I don't mind saying that.
Ain't nobody do that.
That's crazy.
Yeah, no.
One third of this podcast does.
I do vacay.
It's like symbolic.
I'm like, oh, yeah, this is going to feel so good.
Power off.
You see like one more email come in.
You're like, too late, too late.
Didn't see it.
Yeah, and what really happens though is Windows is waiting for the following applications to close,
and it shows you a blank list.
You're like, well, damn it.
Oh, man, that's amazing.
Two-story.
Alan, you're not going to comment you just never shut down man i bet i shut down and every week ish oh somewhere i'm curious to see like the okay so
so going back to the comment uh portion of this episode if you're looking for an idea you could write in your uptime let's see
that'd be awesome what kind of crazy uptimes we get if people have commas in their uptime
then i guess they're doing it right yeah no doubt but they're also not on windows or macs
or they're doing it wrong because they're not up to date with security patches i don't care
what platform you're on.
Eventually, if you're going to install some patch, it's going to require an update.
Yeah, I agree.
I mean, a shutdown.
In fairness, we shouldn't be talking about your Linux server that you've got shuffled away in your closet that you haven't seen in three years.
We're talking about things you actually use.
We're not talking about appliances.
Right, things that you use.
Yeah.
Freelancers and small business owners, I feel for you.
Tax season in here and there's a good chance that many of you are trying to dig your way out from underneath a pile of receipts and spreadsheets.
Do yourself a huge favor and stop digging.
Before you completely disappear under the abyss of paperwork, go and check out FreshBooks cloud accounting software.
Not only
is it going to save you a ton of time and stress, it might actually change the way you feel about
dealing with your taxes. Need to send your accountant a quick summary on the amount of
tax you collected last year? How about pulling together a profit and loss summary? FreshBooks
can generate these reports in seconds instead of hours it would take you to do them manually.
You can even set up FreshBooks to import expenses directly from your bank accounts,
which means next time you use your debit card for that meal, tank of gas, or new computer, boom!
The purchase is recorded instantly in FreshBooks.
All this in FreshBooks is ridiculously easy to use.
It's made especially for people who don't like dealing with numbers and their taxes.
Right now, FreshBooks is offering a 30-day unrestricted free trial to our listeners.
To claim it, just go to freshbooks.com slash coding, that's C-O-D-I-N-G,
and enter coding blocks in the How did you hear about us section and now we're moving on to the
stable dependency principle so we've been talking a little bit about volatility and stability and
we wanted to point out that neither one of those is like particularly a good or a bad thing like
change is good not changing things is also pretty good sometimes.
And volatility is necessary and expected. Now, ideally, components that we expect to change
should not be dependent on by a component that is difficult to change. And when I say something
is difficult to change, one way to measure that would be
based on how many things are dependent upon it. Does that make sense?
I think so. So going back to our website example, right? We want the um database to be stable so we're okay with the middle tier depending on
that database um in terms of the stability and the volatility but we don't want the other direction
we wouldn't want our database to be dependent on the ui since the ui is expected to change
right not sure how we could actually
make that happen but it would be weird if we could yeah we want that ui to be as easy to change as
possible and the easiest way we are one easy way to do that is to print the dependencies on it
so it'd be kind of silly if you had some sort of bot or service that actually uh interacted with
the website to do something like you can you had some sort of bot or service that actually interacted with the website to do something.
Like you can imagine like some sort of integration test or something that actually went out to the website, used the login form, you know, logged in, placed an order, whatever, to do some sort of testing or something.
That's something that's really common with a tool like Selenium or something else to do some sort of like integration or web testing.
But those tests are notoriously fragile because they're depending on code that changes really often.
And that's a bit of a problem.
Luckily, I don't know if too many other examples
where something like interacts with a UI
in order to interact with the program that you control.
Something that would normally go through the server
or maybe even to the database directly.
And so that's kind of an example of us not going through the most volatile
code because it just doesn't really make sense.
And it's a lot harder.
So I think the takeaway here is to not test our UI.
Right.
That's what I got out of that.
That's right.
So components that are dependent on more often are harder to change and that's because
we say they are more stable and we do have some tools to kind of look at our components we talked
about like static analysis to figure out what which of our components are more stable. And I kind of have a hard time saying the word stable
and meaning just that it has more dependencies on it.
That's literally the definition we're going with in this chapter.
And the reason they call it that is because what makes it stable
is the fact that because it does have so many dependencies on it, it's really hard to change because you'd have to go touch all those things that depend on it to ensure that they all still work properly.
Right.
And so that's the only reason it's called stable.
So if you like for anybody listening, if that is that should help you, the more stable it it is the more stuff is depending on it so the
bigger pain in the butt it is to actually change that component because it's going to trickle all
the way up and stable doesn't mean good here no like you know sometimes we'll say like a stable
release it generally means it's like it's good not in this case we're literally just talking
about how many things depend on it yeah it's neither good nor bad neither good nor
bad it's literally just hard to change he does break apart these though um a little bit further
on where he says that if it's so instead of instead of describing stable as the it's dependent on by a
lot of things he calls it responsible right So if other things are dependent on that component,
then that component is responsible.
And if that component doesn't depend on anything,
then it's independent.
And then flip side,
the inverse of that is that
if your component is dependent on a bunch of other things,
then it is irresponsible.
And if it's, wait, what was that?
Yeah, and if it is, and if it can change because of those dependencies, then it's dependent.
Yeah, and so ideally, components that rely on many other components those are the ones that you uh
that kind of by their nature are more volatile meaning it's easier to change because there's
no downstream side effects that you need that you're responsible for yep so uis are irresponsible
not ui developers just the UI.
Yeah, and that makes sense.
Like that they would be volatile, right?
Because, you know, it's ultimately using,
there's this indirect dependency to the database,
you know, and I say indirect
because it's going through some middle tier,
but, and so that database is the stable,
is a stable, you stable you know component right
and we've we've decided that the ui on top of that is um you know volatile you expect that's
going to change so that makes sense that um you know it it would be like that yeah i don't think
i made my point no it does it you did it makes sense that that's going to be exactly that.
The volatile one is the one you can change all the time.
Don't have to worry about it.
Nothing's attached to it.
The database being the one that's transitively attached to,
you can't just change it willy-nilly because you're going to break the middle tier
and you're going to break the UI.
Right.
And so we can actually measure and give ourselves a number for any component
stability by counting the number of dependencies that are dependent on it and how many we are
dependent on and in the formula they give in the book it's basically just a simple ratio but they
they say the fan out which is the the dependencies that we're dependent on is divided by how many
how many dependencies we have plus the dependencies we have out and we end up getting a ratio between
zero one that represents the instability so if i say you've got an instability of 0.1, that means...
Well, zero would be maximum stable, and one would indicate maximum unstable.
So, maximum stable means that you don't depend on anything else, but everything depends on you, right?
That's maximum stable.
Right.
You have things depending on you. But? That's maximum stable. Right. You have things depending on you.
But you depend on nothing else.
So the database would be a perfect example of where if that was your very most ending state, that would be your stable one.
Or we could take this into another context and talk about like from an OS like the kernel.
Yeah.
Okay. the kernel yeah okay okay so the kernel has an i or an instability of zero because it's very
stable because it's got a ton of dependencies on it and it doesn't depend on anything correct
whereas the opposite would be like uh say i guess like a ui that has lots of dependencies
on other things but nothing depends on it So it would be closer to a one
in this ratio. Completely unstable or instable, call it. Instable. Yep. And then if you're talking
about the processes that hook into the kernel, that's sitting somewhere in the middle, right?
Because your UI is going to use these processes that then use the kernel. Now you're probably
falling somewhere in the middle, right? Like you're maybe at a 0.5 or something who knows but but you are both you're somewhere in the
middle of instability there because you have incoming and outgoing dependencies so if we were
to run this formula on each of the commands on our simple website example i would expect that
website to be a one just like we said because it has nothing depending on it and it depends on lots of other stuff um the middle tier now is a
little bit different it has something depending on it the ui and it depends on the database
so i'm going to say that's going to be you know roughly um it's going to be 0.5 right because it's the if we're doing one out over
then plus the out so one over two so it's it's right in the middle now now i do want to back
up here for a second and say from a more realistic more architectural standpoint that we're talking
about typically we're going to be talking about things at a particular tier right so let's say
that we're talking about the middle tier you're going to have talking about things at a particular tier, right? So let's say that we're talking about
the middle tier. You're going to have various components within that middle tier to where the
dependencies are on each other, right? So we talked about logging. You have maybe an accounting thing.
Maybe you have a customer service module. Authentication. Authentication. All kinds of
things. Emailing. Notifications. This is where it all really comes comes in we're grossly oversimplifying
it just so that we can talk about three layers and make these numbers mean something but when
applied more at a particular application and all the modules within the application that's where
this stuff really becomes useful yeah i'm gonna want to see all those kind of guys like i want to
if i was going to use static analysis on the project i'm going to see want to see most of those guys somewhere in the middle somewhere in the 0.5
range to you know some sort of standard deviation there and something like a database that provides
like a foundation and doesn't really depend on much else that should be closer to the zero
so now if you've got an email service or something and it's it's showing as really close to a one or
really close to a zero then
that's something that you want to take a look at because that's something that's kind of fishy it's
in the middle of your stability but it's either got a lot of stuff depending on it that probably
shouldn't be or it has nothing depending on it which is you know just throw away code and what's it doing the cool thing here though is that we've now he learned a way that we can talk about our
the quality of our code in regards to math yes a quantifiable right. So there was an interesting way of expressing this that I wanted to just read where he was talking about like if when it's I is equal to when the I metric is zero, when the instability metric is equal to one.
I'm sorry.
I said zero first, but I meant one.
When it's equal to one, it's the lack of dependence gives the component no reason to
not change um and the components that depend on it may give it ample reason to change so this is
kind of where i kind of got ahead of myself and lost my my point before but um going back to that
ui example right because the ui isn't dependent on things like the database or nothing's dependent on the,
on the UI, like the database isn't dependent on the UI, then there's no reason to not change the
UI, right? If you want to change the logo, you want the logo to be on fire? Sure. Make the logo
on fire. You want to change the color? Sure. Change the color. Like there's no reason to not
change it, right? It's, it's easy. Nothing's depending on it. Right. But, uh, now when, you know, the database tier changes the way, um,
maybe addresses are stored, right. Then the UI might have to reflect that change back out. Right.
So, um, it, there's no reason for that, um, that, that component to not that UI component
to not change, but yet it, because of its dependencies, it can have reason to change.
Right.
And, uh, you know, inverse that was, it says when it's equal to zero, its dependence make
it hard to change the component and it has no dependencies that
force it to change right so nothing's forcing the database to change per se
unless we go back to like non-functionals but let's ignore that nothing's going to force that
database to change but um you know because of the things that are dependent on it it's going to be
really painful to make those changes.
And when you do need to make those changes,
it's a coordinated effort a lot of the times.
And I don't even think we have it in the notes here, but this is, or do we?
Okay, no, this is perfect.
So we do have this and it should sort.
So you're most unstable.
We talked about the website, but let's go into what
we had sort of talked about in, in component things so that you have loggers and database and,
and authentication and all that kind of stuff. When you look at your chain of dependencies,
your higher instability ratings should be at the top and it should go down to your lowest
down at the bottom.
Everything, every time you go down one of those tiers and you look at those dependencies,
anything that's below it should have a lower value.
And that's one of the things that he says here, the SDP.
So the stability dependency, stable dependencies principle.
Thank you.
It says that if the I metric of a component should be larger than the i metric of the components that it depends on so as you're going down that stability number that instability number
should go down yeah if you think about um you know the spotify example where you can listen
on the web you can listen on ios you can listen on your watch, whatever.
Each one of those is, you know, we'll just call them component for now. Each one of those components is at the edge, just the most volatile. So if you want to change the orientation of the
watch, or you want to change the colors on the iOS version, you know, you can go ahead and do
that without affecting anything else. But if you change like the core database or the server server logic then you could potentially have to change all of those those leaf nodes right so
uh it it's a way of kind of um one thing that's nice about this is if you've got this organized
well then someone knows whenever they make a schema update that they can tack on a couple
extra days to that estimate because um you know it's got a
lot of downstream effects yep yeah like uh and if you don't believe me just go rename one of your
tables and see how much other code you have to touch man i actually had somebody to ask me years
ago hey if i change this this column name is that going to mess you up i was like what do you have
to change your query like that was my question back like yeah you change that column name what do you got to do
all right now multiply that times three or four like seriously oh yeah it hurt my brain
you know we can kind of um minimize some of those changes that are necessary by having um
nice clean uh version numbers and and so iOS could depend on our
server project 1.2
and Android could be like 1.1
or whatever.
We could also use the dependency injection
principle to create an abstract
component that can kind of
just act as
an interface between
components and keep things
separated and act as a buffer.
Wait, you mean the dependency inversion principle?
Injection principle.
This is the one that I wrote.
I don't know if that's right or not.
I had mentioned earlier where this might be nothing more than a project full of interfaces.
The project does nothing itself, but it gives you a way to change the dependency flow.
Right.
I'm assuming we're talking about the D from solid, right?
Yeah.
It's inversion principle.
Okay.
I wrote it wrong.
Updating the show notes so that.
Yeah.
All right.
We have awesome show notes.
You should check them out.
We do.
We hope you check them out and you can comment on them.
I even drew the triangle last time.
You should definitely go look at my pretty drawing.
The ultra confusing triangle.
There needed to be a picture of that triangle.
Apparently we're not good at describing pictures.
Especially not triangles.
There's too many sides. Do we need some feedback about that? So many angles. Apparently, we're not good at describing pictures on... Especially not triangles. Not triangles.
They're so hard.
There's too many sides.
Do we need some feedback about that?
So many angles.
I think we had some people who were like, man, I was so confused.
Oh, dang.
Yeah, we were too.
That's all right.
We're going to do it again here in a minute.
Yeah.
All right.
So, the next one we have is the stable abstractions principle. And this one basically says that a component should be as abstract
as it is stable.
And so what does that even mean, right?
So basically the gist of it is
code and stable components
are the hardest to change.
So we shouldn't put logic
that is likely to change in there.
Stable abstraction principle states
that a stable component should also abstract.
So the stability does not prevent it from being extended.
Unstable components should be concrete since its instability allows concrete code within
it to be changed.
So basically what they're saying is create abstract classes or interfaces for your stable
components.
And then that way you can extend those things.
You can, you know, make other things do what they need to do.
And those are sort of your contracts for it.
I was kind of curious about this section because he definitely,
even in the pages leading up to this one and going forward from here,
was referring to the abstract classes.
And then I was like, well, I wonder why the template pattern isn't enough.
Like it's never, it wasn't mentioned in any part of this, but I was like,
couldn't that also help with that, you know,
adhering to the open close principle policy?
Well, that's sort of what an abstract class would give you, right?
If we're talking about,
it kind of does because those are pluggable patterns that get overridden right and so an abstract class though is one that you
would have there is no there is no instance of you'd have to create a class that that inherits
from it yeah yeah i mean obviously to take advantage of the template pattern you'd have
to inherit as well but i was just curious though to me that his answer to this
was only about f-track class and not like other ways that deal with the open close because this
was you know this is we've seen this pattern where at the component level a lot of these principles
there is a corresponding class level principle that goes along with it right yes um and you know
this was along the lines of staying close to the uh open close principle so i think totally yeah
the template the template pattern would would fit into this thing um and for those not familiar with
a template um pattern a template method pattern like like picture you have a class and you have certain methods in that class that
you allow your users the ability to override.
And then you have some other method that will call all of those methods in
order.
And so if,
you know,
one of those methods was overridden,
it's going to end up calling your method. So, you know, I'm trying to think if, you know, one of those methods was overwritten, it's going to end up calling
your method. So, you know, I'm trying to think like, if you had a class, let's just call it,
let's just say you had a method one, method two, method three, and then you had a run method
that calls method one, method two, method three, and you allow your users to, or anyone who's
developing on your class, they could over provide an override to method one or method two and you allow your users to or anyone who's developing on your class they could over
provide an override to method one or method two and or method three and so when that run method
gets called it'll call the appropriate method at the appropriate time yes so it's you know the
temple method pattern is just a neat little way of of allowing your users and users in this context
would be developers, but allowing your users the ability to inject their own functionality
in certain places, maybe in its entirety, maybe they replace entirely whatever the previous
functionality was, or maybe they only replace, you know, a portion of it.
So this is kind of interesting because i mean the whole thing
about an abstract class like he doesn't dictate at least not in this chapter as far as i remember
and maybe it's further in the book is is they talk about the amount and we'll get into some
of the equation stuff here in a minute but the amount of abstractness in it right so i don't know if
he's saying that that that component is being relied upon just basically the nature of it is
abstract right like there's not a ton of implementation in it or what is in it is
fairly bare bones and then if you want to use it you're going to have another component outside of
it that extends or implements that,
you know,
that.
So maybe I read abstract as abstract class and that's not what he meant.
That's possible.
And that's what I don't know.
I mean,
he doesn't,
he doesn't necessarily spell it out completely,
but it could be that,
you know,
you have the abstract classes in there,
but you also have implementations within that.
And I don't know within the component.
And that's,
that's kind of what I'm getting at because. Yeah, no, you're probably right. That's
probably a better interpretation of this, of this portion. But we talked about earlier too,
like we, you sort of almost have to make the leap or the assumption that he's also
assuming to a certain degree that, that you're doing dependency injection. And that could be
part of this as well, right? Like it could be that you have this abstract component down here
and then there's all these other components out here
that could just be injected in that extended that thing.
So it's hard to say there's a lot of interpretations we can make here,
but willing, you know, at least keep that in mind.
So check this out, like our Spotify example, right?
We've got, we'll say um five different you
know kind of clients or uis depending on a server project depending on a database project now the
stability of that server project is really high because it's got five dependents on it so you know
now i guess the the uh the ratio would probably just be one.
I don't know.
My math is terrible.
Anyway, it's going to be really stable, which is unfortunate because that's kind of like the core of our logic, right?
It's the core of our business.
So we've got a problem there where we've got five things depending on one thing, which is really stable.
And we also want it to be able to change really often, like whenever the database changes. So one way to kind of change those numbers is to introduce an abstract module
so that those five UIs depend on that abstract module.
Now that abstract module is really stable.
It's hard to change that abstract module. And we make that abstract module depend on that server project.
Am I cheating the numbers by doing that?
Wouldn't that still have the same indirect dependency, though?
Is that because you count all the fan out as everything recursively?
Or is the fan out just your direct dependence?
Well, the answer.
Okay.
So you had one server project and five UI projects.
So it'd be one divided by five.
So you're getting closer to zero.
It would be maximum stability, right?
Okay.
You're right.
Yeah.
Yeah.
So your answer would be 0.2.
But yeah, I guess he doesn't really say that you would count indirect.
So it can, it can. So if you think about it, you have modified the equation. So in the case of
where you're talking about, let's just, let's keep it simple so that you have the five to one,
right? You're at 0.2 right there. If you introduce that abstract one in between now now you have five
going into it and one going out so now you've basically got you've just moved the stability
to the abstract you have but now that makes the um server side one to one it's one divided by one
so it would be maximum no no it would have no outgoing the server would then be zero
so it would be completely stable it that's yeah it would be the the it would be dependent on by
the abstract right so it would be one divided by one so it would be maximum unstable sorry it would
be one divided by two because it's it's um one over n plus out yeah
well it wouldn't know the out no no it's n over n plus out or out it's out divided by
out okay yeah so it would be zero it'd be maximally stable but the problem is oh no if
it's one divided by two no it's 0.5 it's
right in the middle five wait i thought we said it was zero over man no it's one over one plus one
so that means i messed up my point uh two before then no no instability is fan out divided by
fan in plus fan out so if that server project doesn't reference anything else,
there is no fan out of the database.
Okay, I got you.
Yeah, so the database now is fan out of zero divided by zero plus one.
So it's mostly stable.
It's hard to change.
Yeah.
Yeah, it's really hard to change because it doesn't depend on anything.
It only has some stuff depending on it.
The server now, because of this kind of abstract shim we've put in place, is now more volatile.
So just by adding a simple little kind of abstract module there, we bought ourselves some volatile freedom.
Some wiggle room, basically.
It feels like cheating, though, doesn't it? but that's that's what you do right like anytime you need to change something
that has been dependent upon concrete implementations the easiest thing to do is to
supplement in like an interface and then just change the the piece that was there before right
so so initially like i guess guess if you're thinking about
an iterative approach to swapping something out,
without just having to gut the entire thing initially,
is everything that was a concrete implementation previously,
change that to an interface contract
that's going to be done, right?
And the first step is you put those interfaces in place and
it can still use that existing piece there. But now you can easily swap out those things one by
one, right? To say, oh, it's depending on, you know, I authorization, right? And now you're
changing out your entire authorization thing. So now you can just swap out the back end concrete
implementation that was plugging into the IAuthorizer.
And so you're buying yourself that wiggle room.
So it is cheating, but it's the way to do it without having to hard, you know, almost full scale redo everything.
Yeah, and without that abstract component there, then as soon as you compile that server, you'd have to compile all five of those UIs.
Like the computer, you know, the compiler doesn't know any different by having the abstract module now you only have to worry about those
five leaf nodes if the interface between them changes which is another way of saying is if
the contract between them changes in which case well yeah of course you do then right so it provides
a nice little buffer there it just kind of feels like cheating to me though but i mean that's that's kind of interfaces are
you know they they just provide a clean line and a contract between two things so by um it's just
kind of interesting that it changes the numbers dramatically just by kind of inserting that
little module there yeah okay so let's go let me recalculate then this instability of that abstract component in that example.
So that abstract component is dependent on the stable server side,
but it has five UI dependencies to it.
So we're talking about one divided by five plus one,
right?
So one divided by six.
Yep.
Okay.
Yep.
So it's pretty small, which means
it's very stable.
Correct.
Yeah, stable, yes. Correct.
It means it's hard to change.
So when all those
five UIs were dependent
on our server, it was really hard to change the server.
But we put that little shim in there, and now it's not so hard.
Now it's hard when we change that shim.
When we change that abstract module, we've got the pain there.
But that should be minimized only when it really matters.
That almost sounds like for whatever
reason though that we're breaking that whole sdp thing where it's got to get smaller as it goes
down because now you introduce that shim that's one divided by six now your next one is one divided
by two so it's 0.5 right so yeah your other one was much lower now you went down to a 0.5 and now
you're going down to a zero to your database other way so the
leaf nodes are all ones because they don't have any dependencies they're all um you draw the stable
things at the top right so the database would be in the top of your drawing so when you're going
down you're drawing from the database down oh i was saying the opposite direction either way like
those those five stable things no he's got the instables at the top.
I'm sorry. I'm sorry. You're right.
Putting the unstable components at the top of the diagram is a useful convention
because any arrow that points up is violating the stable dependencies principle.
And later we'll see the acyclic dependencies.
And that's, yeah, that's what's weird is what we're saying is you put that shim in there, it's now
1 divided by 6 and then that's going
into a 1 divided by
2. Well, 1 divided by 6 would be.16
or.17 depending on how you run it around.
But then if you were going from
that shim into just your
I don't know what
we're calling it, the server component or whatever
it was, now that's 1 in
and 1 out, so that's 1 divided by was. Now that's one in and one out.
So that's one divided by two.
So you just went from 0.16 to 0.5, right? And then you're going to 0.0.
So you just violated that SDP principle of everything is pointing downwards.
No, the arrows are still pointing, but the number is not decreasing like you were saying.
No, no, I think what you're saying is right so we're
saying we've got a 0.17 instability depending on a 0.5 instability which depends on a 0.0 or
zero right so what happens is that that means we've got something that's stable depending
something on something that's volatile so the whole point of us putting that little shim project
in there was to buy us some volatility, which we did.
But that's a bad thing because now we've got something that's volatile being dependent on by something that's stable.
And I think really the only reason this is a problem here and what we're talking about is this is such a contrived example in that you would never just introduce one thing.
It's never going to be a one-to-one type thing
when you get down to that level.
You know what I mean?
Like there's going to be multiple components
all depending on that server level.
And I think that in real world,
you would see those numbers play out better.
I don't think that you would ever introduce
just a one-to-one mapping of all the interfaces
that a UI is going to have
into the server project.
You know what I'm saying?
So I think that those contrived numbers are probably money in the waters here
a little bit, but yeah, it shouldn't be.
We're sorry, dear listeners, for going into like,
arguing these numbers and stuff.
It's gotta be really confusing,
but this has actually been really eyeopening for me.
And it actually makes me really happy that my little cheater solution
there is violating one of these other principles. So even though it makes the numbers look good in
one way, it's actually causing another problem. And it's kind of in evidence there and can be
detected by static analysis who can say, hey, the numbers go smaller, smaller, bigger, smaller.
What gives? I mean, this actually reminds me of something that we've talked about that we want
to do an episode on is the onion architecture the whole idea is that your dependencies are
constantly pointing down towards the middle right and that's sort of what this thing is it's
basically anything that has less dependencies are out on this outer ring and you just keep
pointing down until you get into these things that to where you know basically everything's
referencing them.
This book actually goes into something very similar and they call it
the clean architecture. It's like the last
freaking chapter. But they basically draw
the onion and rename
it and probably tweak a few things.
Nice.
Alright. I think Al was doing some math over there.
Yeah, I think so.
No.
I mean because I was just going back over that portion of the book
where he's talking about the numbers because where you were getting not hung up on the number but
where you were talking about like the numbers decreasing in it because it wasn't decreasing
um that it was violating the stable dependency principle. And in the, that particular paragraph in this chapter where he was describing that,
it was a little unclear the first time that I was reading it because his
arrow,
the way he drew the diagram,
it went in the direction that he wanted,
but the arrows went in the direction that he wanted,
but the numbers didn't.
But yeah.
Yeah. So, I mean, to round this out, the gist of it is this.
I'm trying to reread it as well.
Yeah, no, that's fair.
Stable means use interfaces and abstract classes.
Instable, use concrete implementations.
You can change them as much as you want at will.
And your dependencies are going to run in the direction of abstraction so the further you go down towards
those stable items the more abstract they should be meaning interfaces abstract classes that type
of thing even the template pattern another way to say that, if you expect something to be unstable, then you expect more concrete classes.
Yeah.
But the things that you expect to be stable, you should expect to have more interfaces and or abstract classes.
Yep.
Yeah.
I just want to say, I am so glad that we're talking about this back in the day. And back in the day I would read a tech book and then like,
you know,
two weeks later I've forgotten half of the stuff and you know,
it just didn't really stick,
but kind of like talking this stuff out,
um,
hashing it out,
trying some examples,
seeing how the numbers turn out.
Like I feel like it really helps me kind of sink in.
And so we hope we're not annoying you guys,
uh,
dear listeners,
because we love you.
And,
uh,
we think that you should read along with us and let us know what you think in the comments or in the Slack.
Definitely.
We're not done yet, though.
So if you've enjoyed our math so far, then let's bring this together with measuring abstraction.
So get ready. This is propeller hat time it is all right so abstractness
equals the number of classes divided by the number of abstract
plus interfaces sorry sorry yeah abstract classes or abstractions or and or you know abstract
classes and or interfaces yep let me rephrase that sorry let me read operator overloading
abstractness equals the number of classes divided by the number of abstract classes or interfaces
so an example of the abstract module or abstract component, where the only things in there would be abstract classes, it would be number of classes would be, you know, say 100. And the number of abstract classes or interfaces would be 100. So we'd have a class library, say like the database library is probably
a good one, where we've got a, you know, an ORM or something. So each class in there is a concrete
class that maps to a table. And so there are probably no abstract classes or no interfaces
there. And in that case, our number of classes would be say 100 and our number of abstract
classes interfaces would be zero and crap divided by zero error but i'm going to assume asymptotically
that it's zero right so this ratio is another zero to one ratio. Zero implies that the component has no abstract classes at all.
And one implies that the component
only has abstract classes or interfaces.
Yep.
Yep.
And now what's really cool
is we can chart these two numbers.
They're two ratios, right?
And the two percentages call it.
We can graph
both of these on a simple kind of Cartesian X, Y plot and get a really nice point on a chart that
represents our component. And so let's try and describe this chart real quick. We might have to
draw a picture on the nodes.
So it's a pretty simple plot.
If you think about it, you're only dealing with zero and one.
So on- An X, Y graph.
Yes.
On your Y axis, you have your abstractness.
On your horizontal X axis, you've got your instability.
All right.
So zero is completely stable. One is completely unstable
on your abstractness. Zero is you have zero abstractness. One is you're completely abstract,
right? So again, a, your, your abstractness on left, your instability on the bottom.
All right.
Now, here's what's interesting. If you go to one or zero one, which would be, you know, the top left of your chart,
and you drew a line diagonally down to the bottom right of your chart, you'd be at one zero.
Wait a minute.
Let's put some words behind those numbers.
So if it's at zero one, it's in the upper left of this x, y, right?
It's maximally stable and abstract, right?
Correct.
And if it's at the bottom right at 0.10,
then it's maximally unstable and concrete. Correct. And then this line down
through the middle of this chart. So if you think about it like a square now, your 0 to 1,1 square
that you've got there, you've got that diagonal line from the top left down
on the bottom right that's called your main sequence and this is kind of where you want to be
for the most part all right now if we talk about the bottom left of that chart which is zero zero
this is basically completely not abstract and completely stable, correct? Yes.
So it's concrete and stable.
Concrete and stable.
This is called the zone of pain.
And the reason this is the zone of pain is because it's stable, meaning there are many dependencies on it,
but it is completely not abstract and it's all concrete, which means it
is incredibly hard to change. So no buffer, no buffer whatsoever. You have zero wiggle room.
Changing this things means that you have to change every dependency that is hooked into it all the
way up the chain. Yeah. So just a quick summary of how he defined the zone of pain at point zero zero is highly stable and concrete component is not desirable because it is rigid and cannot be extended because it is not abstract, making it very difficult to change because of its stability. Yep. So going back to what we talked about earlier,
if you write code and let's talk about typed languages, because the easiest to sort of box
you into this is if you have a concrete class, let's call it person. And you change that class
from first name to first underscore name everything that relies on that person
implementation now has to change how they reference that first underscore name everything up the
chain right if instead that thing is an interface and and we call this thing i person and i person
is fulfilled by dotfirstName,
then it doesn't matter what that concrete implementation underneath it.
That person class could change to underscore firstName.
But when it returns something back for firstName,
it'll have to map that first underscore name to the interface firstName.
And that's why you get the wiggle room,
because that interface is what everything else knows about.
They don't care about your concrete implementation. And that's why this is called the painted zone.
If you've got only concrete implementations, then everything's tied directly to it. There's
no way to get out of it. So zero, zero concrete and stable is a zone of pain. So what a better
alternative would be is if we are really stable, then we want
to be more abstract. This would be zero comma one, and it's right on that main sequence line
that Alan mentioned in the top left there. So, you know, if we're stuck being stable,
we have a lot of dependencies and we need those dependencies on us, then we want to try and be
more abstract. Alternatively, another way of kind
of fixing that problem would be to get rid of those dependencies. In that case, we say it's okay
to be more concrete, but we need to have less dependencies on us. And that would move us towards
the right side, the bottom right side of that square. And that's also another point on that main sequence there all right and this is where
things get um kind of funny so now we've talked about the everything from the line on down to the
bottom left right now let's talk about what's up in that upper right hand corner which is completely abstract and 100% unstable.
This is called the zone of uselessness.
And I love this.
And we've talked about this in the past when we were talking about solid, Joe.
You remember you're like, you have 5 billion interfaces and nothing actually does anything, right?
This is called the zone of uselessness because if something is 100%
abstract but there's nothing dependent upon it meaning if it's 100% um um instable meaning
there's no dependencies why you have all this abstractness it doesn't mean anything it doesn't
buy you anything there's nothing using it it's it's a waste well another way to say this is you
have a bunch of interfaces let's say you you have a component that's nothing but interfaces,
but nothing uses any of those interfaces.
Right.
That's in this 1.1 zone of uselessness.
Yep.
And they call it the software that inhabit this region are detritus.
That's awesome.
I really enjoyed that.
I actually had a hard time kind of imagining this happening and practice where you end up with something completely in that corner of the zone of uselessness.
But I can very much imagine very easily something ending up in that zero, zero zone of pain where you have like a core library,
which is dependent on by everything and is full of concrete classes.
But the opposite where it's like a UI that's only interfaces,
like how does that happen?
Yeah.
I mean,
I think it can happen only when people go crazy,
right?
Like they learn about interfaces.
They're like interface,
all the things that's where you end up in that top right corner but i would agree
you're more likely in any business environment going to see stuff in that bottom left corner
a lot right just concrete implementations where people didn't use interfaces any abstraction
whatsoever and you're just sort of cornered right like it's one of those things where you cringe
every time you have to change that code yeah and he's only useless this is like when do you change these interfaces like nothing depends
on it so it does like you can changing it's completely meaningless but there could be a
case where like say your static analysis covers your code but you you know provide your code
online or something or or whatever to some third party that actually consumes and uses those
interfaces and so maybe it does make sense and it just kind of uh looks a little strange on static analysis
but that's um that's unfortunate because yeah how do you keep track of or how do you um chart
like what you're doing you know if you make a mistake or something how do you even know if you
have nothing consuming it so maybe you should build at least like a reference implementation or something or throw it in the static analysis
there to keep you you know accountable independent sonar cube there are many options yeah so you know
one thing that i was i was just kind of like thinking about is um one of the things you guys
said was something about like it was stable maximally stable and maximally concrete yes right zone of pain uh no no right because the zone of
pain was uh yeah stable and concrete yep it's really confusing because the eye is instability
and highly concrete. Never mind.
Yeah, this one, I really hate that it's instability.
And this isn't a concept invented by this book.
This is something we saw in the NDPen graphs too,
where instability is graphed on the bottom.
So a zero of instability is the bottom left.
And that's the same as saying stable. So you're constantly tempted to say stable,
which throws you off with the numbers.
And even talking left to right is confusing because of that.
But the graph is actually instability.
So the left is more stable.
Yeah, it's like when you're looking at code
and somebody says something, something, not equal, false,
and you're like, well, hold on, wait a second.
Yeah, that little not is so confusing.
What did you do?
Right, not, not, or a bang, bang object.
Yeah.
And you're like, wait, what did you just do?
Huh?
Yeah.
Okay.
So let's talk about this.
Now that we've drawn a graph and we were able to create a scatter plot of all of our components
on this graph, this very simple, very small y coordinate plane here, we can talk about the
distance from the main sequence. And again, you know, just in case, you know, what is the main
sequence, that was the line going from our top left corner at 01 to our bottom right corner at
10. All right. And that's the good line. Yeah. so we want to calculate that so the distance is going
to be the abstractness uh plus the instability minus one wait is that a divide yeah that was a
divide huh they're a divide did i read that wrong yeah no i'm sorry no i'm sorry let me rephrase that
it's just the absolute value distance is the absolute value of the abstractness
plus the plus the instability minus one yep sorry it looked like a division symbol in the notes
okay so for example um our database project which we set is firmly in the notes. Okay, so for example, our database project, which we set is firmly in the zone of
pain, we'll just say it's got a zero for abstractness and zero for instability. So that
would be zero plus zero minus one. So my distance from the main sequence is negative one. We said
absolute value. So one, which is as far as you can get from the main sequence or as bad as you can get from the good line.
Which isn't good because that means you're in one of those bad zones.
Yeah.
But in this case, it's, you know, it's kind of hard to avoid because database project is just kind of like that.
You know, it stinks.
But it's just kind of a way to show you like that's the furthest away you can get.
And it's going to be a one.
So, you know, one of our UI projects where I would expect it to be much more concrete
and much less stable.
So it's going to be much further towards the main sequence.
I would expect it to have a distance of, you know, say 0.2 or 0.3
because there's no dependencies on it and because it's heavily concrete.
So I would expect those guys to get better scores. But you can kind of imagine like if you took all
the projects in our example there and graphed them all, we get a bunch of little dots. We'd have
sure we'd have one over there in the zone pane for the database because it's the worst the server
would probably be not so great too because um it doesn't really have a lot of reason to be
abstract so it'd be fairly concrete but have a lot of dependencies on it so that would say i'd say
probably would be 0.5 on the stability and abstractness would probably be, you know, like say a 0.1 or something.
So the distance from the main sequence, you know, would be, I don't know, 0.3 or something.
So it would be a little bit further away from that line.
And so it's got kind of a less good score there compared to our UI components, but it's much better than our database server that's pretty cool if you could just kind of imagine all those guys plotted there
to be able to kind of see like overall like how we're doing and you could take a look at those
outliers and decide if you're okay with them or if you want to try and do something about it
yeah so you can even do like um how many standard deviations are your is your score away from that main sequence line?
Right?
And so you want everything to be near that main sequence line.
So you want it to be within one standard deviation away from that main line.
Did they say one in here?
Well, I'm just saying, wouldn't you want it to be within one standard deviation?
I don't remember what the-
You want it to be close to the line.
You want it to be close, but if I remember, I mean, this is going back a while to statistics,
but two standard deviations is typically the threshold for most acceptable-
Yeah, most stuff falls in a normal distribution.
In a normal distribution.
So, anything outside of that would typically be bad.
Because I want to say that one standard deviation is like within 1.4% or something.
Like it's really close.
But anyways, yeah.
I mean, you can use statistical analysis on this and figure out.
Wasn't it like 66% I thought?
I think.
That's what I thought.
86.
That was the magic number.
Man, I can't remember.
But that's only in a normal distribution.
And I don't know that we're saying that we should have a normal distribution.
Especially if we're only talking about number of components.
Because you can have a database component, which is way bigger than, say, your server component.
Or maybe vice versa.
The server component is much bigger than a database component.
And so having each individual dots doesn't really give you a good picture of how important those dots are
well what i was trying to say though is that like if you if you
okay so bell curve standard deviation then that's where we get into like the 68 95 99 rule right
what i'm saying is that ideally if you're if everything is in that on that good line or near
that good line right then you're going to be within that first uh you know one standard deviation
away from it right yep yep that's where you'd like to have the bulk of your code and if you're
within the two you're still okay it's the things that cross that threshold
of the second of two standard deviations away from it that's when you're going to want to compare
when you see things that are closer to that zone of uselessness you're going to have to question
like wait why do i have that is that a mistake right is that just code that we left in there
by accident why is that there and then the things that are in the zone of pain are going to be the
things like the database that you're going to have to look at and go, well, okay, my hands are kind of tied there.
What am I going to do?
And even then, even if you start looking in, like at least in the chart in the book, like they just have sort of outliers in that second standard deviation.
If you get into that situation where there's just a couple of things lying out there, then maybe those are things that you take a look at and say, Hey, what can we do to make this better? Right? Like, I mean,
there's no hard fast rule here.
Like they even go into mapping these things over time,
which is interesting, right? Like if you have a, like you said,
you have a static analysis tool.
And the reason you have that thing is because you have this updated chart of
what does my stuff look like? And so you could say, Hey, wait a second, this,
this project that
used to be in pretty good standing all of a sudden dropped out here we probably need to investigate
what we need to do so circling back to one of the comments from earlier in the show if you include
these tools in your build pipeline then you could be charting the this number over time, as you were saying, or suggesting. So you could track the stability
of your component over time. And if as you see that it becomes more stable, and you didn't intend
for it to be, then you can start to see like, okay, what actually happened. And now, because
you have that in your build pipeline pipeline and you can see that visually,
then you can go back and trace like,
okay, what code was introduced at that time in that build
that started creating this problem?
And you can now action that as well, right?
You see that it changed.
Oh, well, we need to introduce some interfaces here.
We need to drop in some abstract classes or whatever.
And yeah, I mean, it's pretty cool.
Like having those tools available nowadays is amazing because it can really help you round out some of these things.
And we keep saying independent, but I mean, you know, SonarQube would be just as well.
And in fact, SonarQube supports way more languages.
Yeah.
Independence for.NET, SonarQube will handle tons of stuff.
It's for everything.
Yeah, and I think it hooks into things like Jenkins
and other build pipelines as well.
Well, check this out.
So I was just about to say,
you know what would be a cool kind of exercise to do
would be to look at some open source project
with some of these static analysis tools
and see how their their components line up and then i remembered that i'd done this a couple years ago
and actually wrote a blog post about it and so i'm actually looking at i put a link to the show
notes if you guys want to take a look i'm actually looking at a graph of exactly what we're talking
about abstract this first instability and the one i put in the blog post was actually signal r though i think i did reports for all of them and so i'm looking at um
at signal r if you're not familiar with that it's basically um what we call like a real-time kind of
websockety librarian.net yeah that's about fair and so i can see that their core library, just called SignalR, is very unstable, which means there's nothing depending on it.
It only depends on other things.
And it's pretty low on the abstractness.
So it's right within that first standard deviation.
So it's right in the green zone for that main sequence.
And if we look at the things that aren't so much, we can actually see the Microsoft.asp.net signal R core is two standard deviations away.
So it's got kind of an orange color and it's starting to drift towards the zone of pain.
And that's because it's stable, meaning lots of things depend on it, but it's not very abstract.
So still a lot of concrete.
This is interesting.
I mean, looking at this, I don't think any of us really
knew much about this at the time, but looking at this, the cool part is it looks like they did a
pretty decent job creating an application that kept it in this. It's almost like the fat belt
that runs through the middle of this graph, right from the top left to the bottom right.
And they did a pretty good job plotting these things in the right spots.
Yeah. And it's actually really hard to read the graph because so many of them fall right on that main sequence line right and uh and actually in their case it's uh highly unstable meaning
that these are probably client libraries for various different pieces um and they're also
very concrete which is right on the line and it's funny they do have one item squarely in the
zone of pain and it's actually a javascript test library yeah unit test which makes sense yeah
it's what you'd expect right so it's highly concrete but nothing depends on it yep
no no things depend on it everything everything depends on it but it's highly so that's weird
then so why does everything depend on a test library yeah there really shouldn't be much depending on that that's kind of weird so yeah i might
have bundled in my you know like tests or something else that doesn't really make sense to
to look at with static analysis but it's kind of cool yeah that's neat well you could open up a uh
an issue with them and point this out
this stuff's broke this is actually a pretty cool
like there's another graph in there
of SignalR. This is a pretty cool
blog post not to
to my own horn but
this is pretty cool and a lot of
it deals with this kind of stuff that we have
just been talking about. You can see a dependency diagram
and stuff and you can see some really nice pictures in this blog
post. We've got a link in
the show notes and you should check it out.
Muchos gracias.
I think I
actually, sorry to keep
cutting you off, I put
links to the actual
reports it generated for the various projects
in the post.
You should check it out. It's pretty cool.
One
last thing to close this out.
There was this one statement that he says that I really liked,
which is that these metrics are imperfect at best.
And I think that's important to always remember, like, we try,
but just because something is in that zone of pain doesn't necessarily mean
that you did it wrong or that it's awful, right?
You know, this metric can to figure out a way to quantify
the quality of the code, but, you know, don't take it as an absolute.
The quality of the code for being able to maintain and build that code over time, right?
That's what this whole thing boiled down to.
And that's what I think that's for a lot of programmers.
I think the important part here is we all sort of take pride in our code, right?
Like we like to write good code.
We like to write code that we can come back to and be happy about.
But that doesn't necessarily mean it was painless when you were working with other code and other projects and all that kind of stuff. about components in an application's architecture and how can these things fit together in a way
to where they're not painful over time
to keep building on and expanding and all that kind of stuff.
Well, if I could, so there's this guy named Joseph Zack
that wrote this blog article.
And there's a quote that he has in here that says,
the worst code I ever saw was the code I wrote six months ago.
He said, every coder ever.
Yeah, exactly.
Nice.
So, yeah, man.
I was actually looking at reading through the article.
I'm like, I don't really know how to calculate this stuff
because some of my code shows as highly instable
and my code's pretty dang good.
So, now I know that all that meant is that there was stuff depending on it.
And it was concrete.
You know, one thing that was a question, though, about this is that clearly the guys from Independent and Uncle Bob, as they were creating this chart and doing all this math. Like, this was apparently a known thing
because here's two different sources that did the exact same thing.
Yeah.
But, you know, I never really heard a lot about this
outside of things like that, right?
You know, independent conversations or this book.
Oh, man, that link that we're sharing that Joe did a while back from the independent,
that is the chart. That is the chart.
That is the exact thing, right?
Right.
Yeah, you can even see the standard deviations, which I didn't know at the time.
I just thought they were like cool, you know, flavors of Neapolitan ice cream.
Well, they're that too.
Aren't they always?
Yeah.
Yeah.
Oh man.
That's excellent.
The independent blog actually has a diagram of the independent code and like it's
really good too it's only got a couple which are in the uh second standard deviation closest to the
uh getting close to the zone of pain but pretty much right down that main sequence cool
yeah i mean even um scott hanselman has another article that's similar that was talking about
the same zone of pain um his graph was much different with a lot more in the zone of pain
so maybe i just googled zone of pain of uselessness and i'm like mostly seeing
independent articles yeah i mean did independent invent this well you you can just search zone of pain of uselessness and i'm like mostly seeing independent articles yeah i mean did
independent invent this well you you can just search zone of pain graph and you'll find a bunch
of um you know if you if you hanselman's articles from 10 years ago right and he talks about
independent independent yeah yeah yeah so yeah i mean this is stuff that is worthwhile knowing about that again going
back to all this like if you're listening obviously you care about getting better at what you do and
it's nice to think about these things not just in terms of your classes but how these things all fit
together in the end and that's uh that'll make us all better in the long run. So with that, uh,
we will include obviously a link to the clean architecture book and the
resources we like section.
And we head into Alan's favorite portion of the show.
It's the tip of the week or month or month,
whatever.
All right.
It's your first,
you go first.
Oh,
okay.
So, um, All right. It's your first. You go first. Oh, okay. So I feel like a lot of mine have been on a Microsoft path here lately.
And so keeping with that trend, AISchool.Microsoft.com. So you've seen your Coursera classes, you've seen your Pluralsight courses, Udacity, whatever.
So now Microsoft has an AI school with a bunch of modules that you can go and watch similar to how you would on a Udacity or a Pluralsight.
There's a bunch of courses out there and you can learn how to use um you know
it can start basic with like uh you know using python for data science it can get into uh
explaining deep learning all the way into hands-on like hey let's use the cognitive services within Azure to recognize faces or, you know, getting started with using the Azure
machine learning site, right?
So there's some great modules out there.
I thought I would share that as a link, as a resource.
Man, how exciting is it nowadays that you can come to something like this?
Like, just on the first three pieces on this page, this is all free.
There is a two-hour and 50-minute course on a beginner thing.
There is a 16-hour module for beginners to completely learn artificial intelligence.
It's an introduction to artificial.
You won't completely learn it.
It's just an introduction.
Then learn analytics, a 16 hour and 45 minute.
Like we're talking about things that back in the day you spent thousands of
dollars.
Yeah, man.
To even get your hands on it.
Like you could get a really awesome, you know,
head start.
Computer science type education without ever stepping foot on a campus yeah man nowadays
there's so many resources out there it's amazing this this kind of stuff is exciting and what that
i think what that's going to mean though right right i think that that's going to like up the
expectations right like if you are going to be in those schools,
that's what I would think.
It's like, because the thing is,
as something becomes more available, right,
then it's just expected that you have it, right? Like cell phones became more available, right?
So it's just expected that you have a cell phone.
Yeah.
So if you're going to be in a computer science
and like, you know, it's just gonna be more expected, more expected like oh of course you can like find out how to do that
because there's so many resources out there to do it and even if it's not man it just having this
stuff available i mean you could be a step above or a step in front of everybody else if you took
the time to you know kick back and watch some of these things and try them. So that's a killer resource. Yeah. And these, these, the,
um,
skill levels,
they,
they go from beginner to intermediate to advance.
So,
uh,
there's a ton of the beginner ones in there,
but you know,
there are some that are in there that are advanced.
So have fun with it.
Killer.
All right.
Um,
you know,
what's funny is,
uh,
things have never been easier to learn,
but there's never been higher expectations.
Like I got my first junior dev box.
They were like, make this div blue.
And I did.
And they're like, oh, you're hired, buddy.
So, you know, things are different.
But then again, think about it this way.
Like that was not easy knowledge to come by.
Like I had to piece that together, you know,
by buying a book at Barnes and Noble and, you know,
working through a couple of chapters and whatever.
And looking at other websites that actually had a blue diff.
Yeah, that's right.
All sorts of cheating.
But with that same level of effort, say they call it a couple hours,
you know, that used to take me to get that div to be blue.
You can spend three hours learning, you know,
introduction to machine learning or to AI or whatever.
So that's pretty amazing. that three hours learning you know introduction to machine learning or to ai or whatever so uh
that's pretty amazing you know and would you rather spend three hours to make something blue
or just spend three hours to learn how to uh detect whether something's a hot dog or not
now now here let's put it into a different context because like obviously we only talk
about this as it relates to uh you know things that are in like a computer sciencey computer
engineering kind of world but i
mean same is true for everything else everything man you want to learn something about finance
you want to learn how to be a plumber right yeah go to youtube right yeah it's amazing i love the
i love that's a thousand years ago you're like okay i want to be a farmer like all right day one
here's a shovel start digging we've printed we've almost gotten to the point
where the matrix is reality where it's like suddenly like i need to know how to fly an
apache helicopter okay there it is done yeah yeah zap zap it's amazing we're almost watching the
video right now all right so mine is is actually something that my buddy nicholas that i work with he shared with us and it is called
quicktype.io and what it allows you to do is in a number of different languages paste in some data
and it'll create the classes for you so if you have a json blob you can drop that thing in there
and it will create you a c-sharp class a um probably python java whatever uh drop some xml C sharp class, a, um, the probably Python, Java,
whatever,
uh, drop some XML in,
it'll convert it into class type information.
So,
now,
um,
didn't you give a very similar one that was within visual studio that did the
same thing?
Yeah.
A long time ago,
it would take,
um,
XML,
I thought it did XML and JSON and JSON, and it would turn it in c sharp but it was kind of ugly i mean i left it as a tip and i tried it a few
times and i wasn't as happy as i thought i'd be but this one this one created good clean code
this one looks really nice yeah this one creates some some pretty stuff and you can pick the out
language the out language so like right now i'm looking at there's a JSON blob and you can have it convert to C Sharp, Go, C++, Java, TypeScript, Swift, Elm, JSON schema or simple types.
So, yeah, man, it's really good stuff here.
And the input types are JSON, multiple or schema.
So I think I'm pretty sure I saw some XML that worked with it. So yeah, really cool stuff,
man. Somebody took time to build this little app and free. Go try it out. I like that.
I keep finding myself doing more and more stuff on websites rather than using apps or even stuff
on IDE. I even do calculator stuff now. I just tend to search it and get the answer from Google
rather than like opening up the calculator app. Yeah.'t know why well i mean i i'm very much like that too like back in
the day you know in sublime you would install all your favorite like uh json formatters and xml
formatters and things like that and now it's like i just go to the web i I shared a tip about JSON formatters a couple episodes back.
I don't remember how many it was, but yeah, I do that.
So now I just go to that website.
I think it was like Curious Formatter or something like that.
I Google it.
I love these utilities.
Yeah.
I mean, people all had a need or something that was bothering them,
and so they created these utilities.
I actually thought about something the other day.
So our buddy Ryan, who –
So they're very stable.
They are very stable.
A lot of dependencies.
He wrote Glyphrend, which has now gotten a ridiculous number of downloads.
But he created the plug- plugin that allows you to find,
you know,
icons or,
or,
or images that were from font awesome and various things within,
in your ID.
Think about this.
Anytime you have to all tab out of something you're doing to go get
something to,
to augment something you're doing is probably a good idea for some sort of
plugin or some sort of utility.
So for anybody that's looking for a little project to do,
there's you,
there's you something to think about.
As if you didn't already have enough things to do.
That's right.
Right.
Machine learning.
People ask all the time,
like what's a good idea for a small project or learning or something like,
Hey,
make a calculator plugin,
make your calculator website,
make a whatever.
Yeah.
Command line.
Little stuff. It doesn't have to be big. Yeah. Make a calculator website. Whatever. Yeah. Command line. Little stuff.
It doesn't have to be big.
Yeah.
It can still be really useful.
Yep.
Speaking of useful, my tip is a new app that I just started using called Habitica.
It's the new year, 2018.
I'm trying to develop some new habits.
So I kind of looked for some gamifying apps that I could use.
And if you're watching the video, probably not.
This is a cute little picture.
So I've got like a little role playing game character on here.
I made myself look like a wolf, I think.
And I get points for doing little daily tasks I set up as well as some bigger to-do lists type things.
So today I lost a little bit of health because I had a not a very healthy
lunch. I didn't do cardio. I didn't do 10 minutes of cleaning. I did walk the dogs. I did floss. So,
you know, I got some points for that. So, these little things I just kind of check off. And so,
it's kind of a fun little thing. Whenever you go in to check something off, a lot of times I'll
notice like, oh, I walked the dogs, but I still haven't washed the dishes today let me go ahead and do that so
it's just kind of gotten this kind of cool little rhythm where it kind of encourages you to kind of
think about the little stuff you should do so it's not scheduled dentist so it's gamifying
the habits or to-do list in your life so the things that you want to be good habits you're gamifying it have
you saved the princess yet no um actually there's all sorts of little quests you can do with other
people and so one of the incentives is like well i want to level up and get stronger and earn money
so i can go buy a sword so that the three of us can go you know take out the big uh you know
minotaur boss or something and so i don't think there's any like
actual fighting component but it just encourages you to kind of build that power by doing stuff
every day but this is all kind of stuff this is all on the uh honesty scale right like yeah oh
yeah you could totally hit a button said you have lost yeah i mean you beat the minotaur you know
it's not gonna you know give you a sandwich or anything.
So, yeah, there's not a real strong incentive to cheat either, unless you're just trying to kind of make it look like you're doing better than you are.
Well, isn't that what Facebook is?
I mean, like 90% of people on Facebook.
That is true.
So, yeah, maybe I won't add you guys as friends on here then.
I ended up using this one.
12 miles.
Sorry.
Yeah.
I ended up going with this one because it looked cute.
So it looked like a cute little video game.
It's also open source, which I thought was really cool.
So you can go contribute to it.
And it's on Android, iOS, and it's totally free.
And you can actually, I did support the developers. So I looked like a wolf because I like, you know,
I'd click the little option to buy developers a coffee and they give me you know some money for skins so that's totally
optional though cool hey speaking of android and ios didn't you just recently make some sort of
life change uh yeah i switched to i switched to android because you know headphone jacks and
my i had noticed that my computer had gotten or my iphone had gotten suspiciously slow after a latest update and this was before all that stuff came out about uh the
battery and it may not be related to the battery but it was like hey i updated now my life is
miserable so i've still got it here if anyone wants to buy it it's got a cuck screen how much you're selling it for uh whatever google says it's worth oh come on man
you want to buy a busted iphone you had a six
uh yep six yeah it's not terrible i haven't had an iphone in a while it's another music
player device in my house yeah sure we'll talk about one of those awesome all right well uh i think was that it yeah yeah just a quick summer we talked about
component coupling we introduced three new principles the cyclic dependency principle
stable dependency dependency principle stable abstractions principle and we talked about
stability and abstraction how to graph things,
which can be a little confusing.
But if you go to the show notes,
we've got a couple of examples we can point you to of what this looks like.
And you can kind of wrap your head around it.
Slash 72.
All right.
So with that,
subscribe to us on iTunes,
Stitcher and more using your favorite podcast app and be sure to leave us a
review by visiting
www.codingblocks.net
slash review.
And we forget this every time. If you guys
would like some stickers, send us
a self-addressed stamped envelope to
www.codingblocks.net slash swag.
And also while you're up there,
check out our show notes, examples,
discussions, and more.
Get and send your feedback questions, rants, I don't know, to the Slack channel or hit us up on Twitter or some other way.
If you find us anywhere and just ask us, we can point you to where we'd like for you to go.
Way to be definitive.
Yes, it's kind of a raw deal for you, really.
So anyway, hit us up and we'll tell you what we want from you.
That would be fantastic.
And at Coding Box is a great way to do it.
Or you can go to the website and find lots of shoutouts and stuff.
Social links.
That is a wrap on a very short show.
Yeah.
Tank of gas or a new computer?
Boom.
The purchase is recorded instantly in FreshBooks.
All this and FreshBooks is ridiculously easy to use.
It's made especially for people who don't like dealing with numbers and their taxes.
Right now, FreshBooks is offering a 30-day unrestricted free trial to our list.
God, I was doing so good.
It all started with computer.
Downhill from there.
I turned my computer off once a day.
Dang it.
I was like,
you know what? I can deal with computer.
If I just get through it, I can deal with computer.
I won't let computer get the best of me.
Yeah.
We'll do it live.