Two's Complement - Semi-Solid Principles
Episode Date: March 24, 2021Matt and Ben join an argument on the Internet, which is always a productive and rewarding use of one's time. They discuss the SOLID principles from two different perspectives, and judge them. Listen i...n for the verdict. Then, Ben ponders how programmers learn, and whether sailors are happy. Matt gets a new puppy.
Transcript
Discussion (0)
I'm Matt Godbolt.
And I'm Ben Rady.
And this is Two's Compliment, a programming podcast.
Hey, Ben.
Hi, Matt.
How are you doing?
I'm doing great.
So we don't usually try and make these things in any way
timely we just talk about stuff that is you know true forever but a friend ex-colleague of ours
recently posted something rather inflammatory about something which is dear to the hearts of
many and i my sodding dog is making such a noise behind me we're gonna carry on i'm afraid i am dog i'm puppy city yeah we have a guest on
this week's podcast special guest is is uh yeah is monty who is a 12 week old uh black lab and is
is currently in the pen behind me anyway the solid principles are things that are sort of
taken mostly as truth by a lot of people i'll'll see it in code reviews all the time. People say,
hey, this doesn't conform to solid. And Dan recently posted a blog entry that's sort of
taking it down. And we figured we should talk about that. Now, I'll be totally honest with you.
I've been a software engineer for 20-ish years. And I don't really know what the solid principles
are. I just kind of people say about them and I'm like oh yeah sure i'll refactor my code in the way that you said
right so right i'm gonna look to you to teach me first of all whether what what they are and then
maybe we can talk about some of the things dan raised and maybe you've i know you'll have opinions
because yeah because you're ben i have opinions this is this is. This is my gig because I have opinions. What are solid?
So, yeah.
So, let's talk about solid principles.
So, just obviously all of our listeners can Google solid principles and know what they are.
All of our listener.
All of our listener can Google the solid principles. But just for those who are in mid-podcast and don't want to be bothered, they are S stands for single responsibility principle.
O stands for the open-close principle.
That's the most confusing name.
Yes.
We'll talk about all of these.
We're going to talk about all of these principles.
You go through them first.
L stands for the Liskov substitution principle, named for Barbara Liskov, who presented that in a
presentation in the 80s, I think, is when
she proposed that.
I stands for the interface segregation
principle.
D stands for the dependency
inversion principle. So those are the
solid principles. No wonder.
I mean, I can't imagine why I never
committed that to memory. It seems so obvious
in retrospect. Yes.
Uh-huh.
Right.
Of course.
So, yeah.
And the controversy is particularly interesting for me.
I never really had the opportunity to work directly with Dan.
He was sort of around and about at PrevPrevCo for me.
You know, I ran into him a few times and had some conversations with him.
It's not like we ever sat down and wrote code together, but I sort of talked to him and was very interested to hear a lot of his ideas.
I did actually work a little bit with Bob Martin when I was at Object Mentor back in the 2008-ish timeframe.
And as we had the guest on before James, James Grenning also worked with
him at object mentor. And when I was at object mentor, the solid principles were definitely part
of the, you know, curriculum, I guess I would say that we would, that they would teach in their
training sessions. Right. Um, and so, you know, that was something that was, it was very much a
part of that. And I think, I think Bob is kind of known for promoting those principles as good principles of design. You know, least he had in the back of his mind, Bob would be one of the people that he would be... If I were framing such an argument,
I might sort of assemble a virtual panel of people in front of me and sort of argue with
them in my head. And if I were Dan, I would say Bob would maybe be one of those people.
Bob would be another... Yeah.
Yeah. Yeah. So, I have a little bit of... you know, I can see both sides.
I've had direct contact with both sides of this war.
War is a strong phrasing.
Let's not phrase it as that.
Yeah, I know.
I'm being a little funny here.
I don't really think that there's actually that much of a controversy here.
No, sure.
But I can definitely, I feel like I can argue both sides of this argument. and i have my own sort of take which is not really in the middle it's sort of like
a third thing off to the side um so we can maybe interesting throw that into the mix and evaluate
that for honest merits interesting but let's let's talk at least briefly let's do like a one
paragraph so that i at least i understand what each of those S-O-L-I-D things.
So the first one was what?
It was-
Single responsibility principle.
Okay.
That one, I recall something when I was working at Google, it was sort of boiled down to me
and transmitted to me into, or rather it stuck in my memory.
And maybe you can tell me if I'm actually right on this one.
It's like, if you're writing the description of a class and you use the word and then maybe
just maybe that class is doing too much so you want to like break it into two classes or something
like that and i in my mind i've combined those with with the s of solid right that's what i
think of when people say single responsibility i mean like yeah if i can explain what this is doing
it's a price class it holds a price well there you go i think that's probably it but you know if it's the uh um i i'm now i'm not going to come up
with any good answers but if i have to put the word and somewhere when i'm trying to describe it
price and quantity right well yeah you see that's where it gets tricky right no because you just
you'd call that an order or you'd call that a like there's another name for that right
well that's not true so yeah you've picked that's a perfect example unintentionally because it's
almost like you thought about this before but price and quantity is a really convenient abstraction to
have in a trading system because you always want to place an order and an order is not a price and
a quantity an order has a price and a quantity but then so does a an order that's
resting in the market so does your maybe your risk limits in some ways are related to these
things there's there's a number of ways where that tuple of a price and a quantity going together
is a useful thing of itself but it doesn't really have two responsibilities it just holds two pieces
of information maybe that's where you're you're now you're nodding at me like yeah i mean these a lot of these are heuristics, right? Like the heuristic that you got at Google is
if you're putting the word and in a class name, think about it, right? Like, you know,
are you putting together? And I think a lot of this, there's a lot of,
I don't know if this is good or bad, but my experience as a software developer has been a
lot of this is almost like an oral history that gets passed around from developer to developer about here's the things you should generally
do and here's the things you generally shouldn't.
And the interesting thing is that the oral history among a lot of developers turns out
to be the same in a lot of respects.
And I think single responsibility principle is one of those.
It's sort of like the Unix principle of do one thing well, right?
There's a lot of, and you can find other examples of this where it's like, you know, keep things principle of do one thing well right uh there's a lot of and you can find
other examples of this where it's like you know keep things focused do one thing but then the
arguments sort of come in in terms of like well what do you mean by one thing right one thing is
a different thing because like my my price class can also represent itself as a string and it can
be formatted and it has all these other things so like if you were to describe the responsibilities
of my price class it would be wraps the abstract notion of the value of something and can represent itself and perform arithmetic on itself.
And before you know it, you've got like 100 ands then in a useful class.
Right.
But they're not really – yeah.
Yeah.
They're not different responsibilities.
Yeah.
What do you mean by responsibility?
Is IO a responsibility?
And what do you mean by single?
Yeah, exactly.
It's like –
What do you mean by, what do you mean?
Is that too much?
No, okay.
Right, right.
And I mean, I think that this actually going back to sort of, you know, Dan's comments,
I think this is part of what Dan was good at getting at is he was, you know, he was
saying, you know, don't worry about single responsibility, just write simple code, right?
Right.
And- I sort of maybe
think as i was reading this actually of your the thing you've mentioned uh before uh the one
seconds worth of like microservices like is that there's it's really hard to measure how
big something is you have to kind of come up with some heuristic and you've used time of before now
as like well how long does the unit tests for this bit of code work and that's an interesting
way of measuring it as well.
Yeah.
But it's arbitrary, right?
To each their own.
Right.
Yeah.
Right.
Reasonable people could disagree about what it means to be small or simple.
Mm-hmm.
Mm-hmm.
Yeah.
So, I mean, so for me, the way that I interpret the single responsibility principle is sort
of the inverse of another principle that is not in this list, the dry principle.
Don't repeat yourself, right?
Right.
Where the litmus test for me is something like this.
If my boss comes to me and he says, hey, we need to change this business logic, right?
And I, with the knowledge of the code, look at the code and say, okay, but if we change that, then we're also going to have to change this.
His reaction tells me whether or not I followed the single responsibility principle correctly.
If I say, well, we're going to have to change this, if he says, oh, great, perfect, that's
exactly how it should be, then I know that I followed both the single responsibility principle
and the dry principle correctly. I have one place in the code where that business decision is made, and it is impossible
for me to change it without changing the things that it depends on. So, it's like if that wasn't
true, and I changed this, and then two weeks later, he came to me and be like, well, you changed that
thing I told you, but then this other thing broke. I'm like, oh, yeah, were those supposed to be the
same? He's like, of course, they're supposed to be the same. I go, oh, sorry. Then I haven't followed dry in that case, right? But if he comes to me and he
says, well, we have to change this. And I say, okay, well, we'll also have to change that. And
he says, why? That's dumb. Why would we ever change that? Then I know I haven't followed
the single responsibility principle and I've squished two unrelated things into one thing,
right? And so this is kind of the thing with dry too, where it's like you can have two pieces
of code where the code is identical, but the reasons for that code to change is not.
And unifying them is actually making your code worse because now you're in a situation
where you change-
You're coupling things.
You're coupling things together.
You change one thing and you're changing something else that's totally unrelated.
And that behavior needed to stay the same while this other behavior changed right got it and you can have a
situation where you have two totally different pieces of code that are in fact the same thing
and what you should be doing is refactoring that code so that it looks the same and then unifying
it right got it yeah so you're driving it from a business sort of point of view, from the idea of like, yeah, which obviously not all of us have the same experience of having a direct business owner that can tell you that kind of stuff.
But you're kind of like conjuring up in your mind's eye the sort of pointy head boss to measure these things in this sort of slightly thought experiment way. Yeah. Well, and I personally don't think that all that it's, it's impossible for me to say without understanding the context in which a
program is going to be used,
whether or not,
for example,
two pieces of code are duplicated,
right?
You can show me two pieces of code.
I can say like,
yeah,
that's the same code.
I'm not going to tell you that you should unify them unless I understand how
the code is being used.
Right. You can't separate that understanding. I'm not going to tell you that you should unify them unless I understand how the code is being used. Right?
You can't separate that understanding.
That's part of an engineer's job is to be the bridge between the technology and how the technology is being used.
Got it.
So, and I think a lot of the Sala principles have to be thought of in that context of like, you know, how is this actually being used? So we've covered the S of solid,
and I think we've done at least some justice to Dan's point about it,
meaning many things to many people.
And so maybe we should move on to the O,
which, again, I've already forgotten what O is.
Open-close principle.
Open, I mean, again, trivial.
Trivial understanding now.
With a single letter O.
Yes.
So what is open-closed?
What does the open-closed principle mean?
So the pithy phrase here is that code or a module or a class or however you want to scope it should be closed for modification but open for extension.
Right? should be closed for modification, but open for extension, right? And the way that I kind of interpret this as is if you have existing behavior that you don't want to change,
you shouldn't have to change it in order to add new behavior.
Yeah.
Now that's, and that's a goal, right? You're never going to be able to achieve that 100%
of the time, but like to the extent that which you can do that, what this principle is
saying, and I'm not saying that this is necessarily true, but what this principle is saying is,
is to the extent you can do that, you have produced a better design. Design A is better
than design B because it is easier to extend and you don't have to modify. Now, this is a place
where I have a lot of sympathy for Dan in that, like, a lot of what people sort of get into with this is reuse, is designing for reuse, right?
They want to write code that can be easily reused.
But that isn't always the right goal for anyone.
Right.
I mean, I'm pretty short reuse most of the time when it comes to, like, I like to discover places where things are reused and not try to predict where they're going to be reused.
That's a nice, yeah, that's a good analogy.
You discover it.
It's an emergent property of the code and the way you're going.
But very rarely do you set out and go, I'm definitely going to reuse this.
I'm going to polish this beautiful reusable gem only to discover it's used in one place in the code.
Or indeed, you've hamstrung yourself by making by making it so difficult i wonder i often wonder if there's
like a strange legacy in programming where it's like you know in the beginning there was ones and
zeros and then we invented languages right and so, a lot of programming, you know, this sort of oral history
comes from the problems of language designers, right? Because that was sort of the beginning
of programming, right? Of, like, you know, the design of programming languages. And a lot of
those problems that language designers face sort of got held up as the important problems to solve.
When really, if you're just building like application code or even certain systems code,
like that's not really the main problem that you have, right?
Like a big problem for me isn't creating a reusable standard library that is easy to
use correctly and hard to use incorrectly, right?
Like that's not a problem that I solve.
Occasionally I do, but not very often, right?
Whereas, you know, if you're designing a language,
that's a lot of what you're doing, right?
Of course.
And so, you know, to me, the open-close principle
sort of falls a little bit into that category,
which is, you know, it's useful in certain situations,
but I certainly wouldn't make the claim
that code that follows the open code principle
is just always better than code that does not.
Got it.
This definitely falls more under the sort of guidelines
for measuring a design, perhaps,
but somewhat in a vacuum
rather than being specifically in my use case.
And from my experience as well,
like the tooling has changed significantly
and the way we build software has changed maybe since this.
It's not an, you know, OO, which sort of,
to me when I hear that, the open closing,
I'm thinking of like, oh yeah, this is a class
where you've got extension points that are like overridable,
but you don't necessarily have to.
That's obviously one way of achieving that kind of thing.
But it smells like that's that's the way perhaps you would be uh wafted towards by the
sorry that doesn't make much sense but yeah it feels ooe to me and it doesn't have to be and
and so you know like again with with um modern tooling now if i need to change a piece of code
it's not scary to open it up i have tests to protect me from like other people's pieces of
code and if i need to just go and change something i can go and change the code and use a refactoring tool to add things
all these things are in there so it doesn't seem as frightening now if i was publishing a library
and it was v 1.2.7 then i'd have to think about it which i suppose goes to your point about not
all of us are writing libraries all the time most of us are just trying to get the next version of your app
or your code deployed, and code reuse is not such a big deal.
But obviously, a good design still can be beneficial, right?
If you start out with a giant list of strings
that everyone has to kind of edit in three places
to add another string in in order to extend your library
and make sure they all agree, that's a bad design,
measured by any axis, right?
So if you
yeah yeah yeah i think at a certain point application of the open close principle in most
contexts just devolves into decoupling right and this is again kind of getting back to dan's point
about like just write simple code right like okay i think it's a little bit more nuanced than that
but you know the open close principle really when you get down to it, is just things should be
decoupled from each other so that you don't have to change things in four places. Or if I'm reusing
a function, I shouldn't have to read all the guts of the function to understand how it works or
change it or all that stuff. But I think that the main application is, like you say, if you're
building a library or something like that, you really want to think about it.
If you're building a library that is going to be used by somebody that you will never meet, you know, as opposed to someone else in your organization, you want to think about that.
But, you know, it's just that one is much more about context, I think, than the first one.
I mean, just in defense of like the library writing thing i'm just going to very briefly uh every now and then i've written i've prematurely created a library
shall we say and designed it a little bit more than it perhaps needed to do
and probably one in 50 one in 100 times i've done that someone else has discovered it and gone oh
this is useful and then used it for things that i didn't originally plan it for it which is great right but i don't think the benefit of people finding those libraries
and then using them and then emailing me and kind of going yeah thanks for that thing by the way
we've been using this all the time in our in our side of the business and how that's great wonderful
um but that doesn't outweigh the the pain and suffering that one goes through trying to design
for something where you you're you where you're trying to invent a customer
you don't have to design your software
so that that customer can reuse it.
Yes, yes, yes.
Speculatively doing that is like, you know.
And it's a tax and it's expensive.
Yeah, it is. It's way more expensive
to write library code and reusable
code than it is to write something that's like more
application focused for sure. So then L.
Yeah, L. Barbara Liskov Substitution Principle principle which means you can switch in barbara anywhere
you like yep you can any barbara shaped object can be replaced with a sub barbara that is equivalent
in every respect um no i i actually i don't know if this is true. I was trying to figure this out when I was reading Dan's thing of like,
I have heard that Barbara Liskov proposed this as an argument against inheritance.
She was like, if you were going to make an inheritance system,
it would have to have this property, which is a ridiculous idea.
So inheritance, therefore, is a ridiculous idea.
Oh, it was a reducto ad absurdum.
Yes, yes.
The unfortunately was just went, oh, we have to be absurd then.
Yes.
Maybe one of our listeners can point us to a reference on this, because I was trying
to find out whether or not, I've heard this, I don't know if it's true.
You've heard it right.
I want a reference that says that, yeah, no, that's what Barbara Liskov meant when she
did this.
And so, it's super ironic that it's in the middle of this list of principles.
This, to me, is something that is very much about object-oriented design.
If you are writing code in a functional language, it's not something that you ever really think about.
I mean, maybe a little bit in corner cases, whatever,
but it's certainly not risen to the level of
this is what it means to write good code, right?
So, you know, the basic idea here is that, you know,
if you have an interface, if you have an abstract class,
and you have a subclass or a subtype,
then the behavior and the definition of behavior is a little bit nebulous here,
but the behavior of those subtypes should be indistinguishable, right?
So you can swap out any subtype and you get the same behavior, quote-unquote, from the client.
You see, that's where – I mean, I think I understand where this is going,
but that description or descriptions like that are inherently extraordinarily confusing
to my pragmatic day-to-day use of subclassing and interfaces.
Like, the reason I have an interface
is so that I can have things that do very different things
when you call, you know, what is your name?
They don't all say, I am an animal.
They go, I'm a dog or I'm a cat,
because those are the only obvious ways,
or I'm circle lines, pick your oh standard now it's i think it is kind of important to say that like this is
from the caller's perspective right okay so it's if the if the internal state of a class changes
differently depending on which subtype it is like that's completely fine but that's hidden away from
the caller right right they don't
they don't know that anything is different so from the point of view of the contract between the
caller and the callee there should be no sequence of events without you know reaching exogenously
to the file system and kind of going did you write a file or whatever i shouldn't be able to puppeteer
an object that uh i've been given and work out what it is just by using the API, the callers API.
Yeah, yeah.
They look the same, right?
It's not like you go, well, if it's this type,
you have to call free.
And this one, you don't have to call the free thing
because, you know, hey, it doesn't matter
because it's not actually allocating anything.
So you're like, no, no, you always have to call free
even if it's a no-op in the derived class or whatever.
Right, right.
Because you have to treat them all equally.
You're not allowed to go is instance, for example.
Right, yes, exactly.
Which is the, you know, the hit the back door that we all end up having somewhere.
Sometimes.
I would never do that all the time.
No, of course.
I only do that sometimes.
Yeah, and I mean, I think Bob would say, in fact, I know that Bob would say, because he's written
about this, that this is much more about polymorphism than it is about inheritance, right?
And you can have this property in languages that are not strongly typed.
You can have this in languages like Python or Ruby or JavaScript.
I was going to say, it just smells like duck typing.
Yeah, it can be duck typing.
Pragmatically, in strongly typed languages, this often comes down to like
function signatures, like things can't be following this principle if they don't share the same
function signature, because then, or method signature, because then you have to know which
one you're calling and pass it the right arguments. But, you know, again, I kind of see this as an
artifact of object-oriented programming with a lot of inheritance hierarchies which i tend
not to use anyway and a lot of polymorphic behavior which i use sometimes but again it's
like does this really rise to the level of like the top five principles that you need to be aware
of when you're writing code like yeah no not really no it seems not i mean there are equivalents in
functional languages right matching on different, I suppose you could argue,
is a sort of polymorphism like you're depending on these things.
But yeah, you're right.
It seems very specific to a particular popular in the 90s programming paradigm.
Yes, yes, yes.
And it made a nice, neat, backronym-fitting L
in the middle of an otherwise cool, you know, soyed.
It would have been like, what?
No one's going to want my soyed properties.
Yep.
Find an L.
And, okay.
So, that's the list I'm supposed to do.
And the thing is, is that it only gets worse from here, right?
As we keep going through the-
We're scraping the barrel of letters.
Yes.
We started strong, and now it's like, as you go, it gets even more and more.
This is very clearly about a very particular kind of object-oriented design that, again,
if you're still doing that, then you probably know these already.
But it's like that.
So interface segregation, you're keeping the interfaces.
So you have an interface to a thing.
This is the eye, right? We're on the the eye right yeah yes we're on eye right now um you have an interface you want to keep that interface as narrow as you can get it so that the clients don't don't depend on
things that they shouldn't and so that the implementers of those interfaces have the least
amount of burden in order to implement again this is very much about like inheritance hierarchies
and interfaces
and yes and no i mean the interface can be a library interface presumably too like you like
hey my library exposes exactly two functions it has allocate and it has free yeah there isn't a
thousands of other and the only reason i bring this up is because something you mentioned there
was like um to reduce the burden on calling things that you shouldn't be calling on. It made me think of Hiram's law,
which is the law that anything you expose,
no matter how intentionally or otherwise,
will become relied upon by somebody at some point,
given enough users of your class.
So reducing the footprint of that seems like a good idea,
and that can happen in C libraries as well as C++
or other object-oriented languages.
Sorry, I'm very focused on specifics here but yeah so yeah no no that's that's a good that's
an excellent point um and actually you know now that come to think of it i was making a very
similar argument to that in an earlier podcast when i was talking about file system abstractions
and mocking you remember that yeah i was saying that constraining yourself to a limited number
of file system operations makes it more likely that you can swap other things out, right?
Absolutely, yeah.
If you don't think of something as a file, you think of it as a sort of abstract stream.
It might be a socket or it might be a pipe, right?
Like, that is good.
I kind of think of that as a very liberal interpretation of interface segregation principle.
Yeah.
When they say interface in in
isp i think they literally mean like a typed interface the actual keyword interface is
probably involved somewhere in that's what i i i can be talked off of that opinion for certain
okay and i honestly i'm not going to useful i think it's more useful if you do and you know
to your point of like thinking of it as more of a general lowercase I interface, not capital I type interface.
But I think it's more useful if you think about it that way.
But yeah, I was making that exact argument not but a few podcasts ago.
So maybe I should.
In the strange time space of podcast.
Yes.
In podcast time.
So that's I. That's's i and then the last one d
dependency inversion principle basically he's just like dependency inversion principle is
you want high level things depending on other high level things not low level things
right and it's like yeah okay so if you have an, let's take the object-oriented example here.
You have an interface that takes an argument.
That argument type should be probably another interface and not a concrete class, right?
Like you don't want to constrain the implementers of that interface to say that they have to
take this particular concrete class.
You want them to
depend on a higher level abstraction which is again an interface or an abstract class even
rather than a concrete class right this is where like anyone who programs c++ is going uh we try
not to do that here or you know like there are various reasons why but we've talked about that
before so in the abstract high level components depend on
other high level components rather than reaching down into the the guts of of of the class hierarchy
and having this sort of um well i guess that's the inversion of the the dependency inversion
is like having this dependency on on a low level thing which then maybe depends on a high yeah no
i cut you off halfway through the explanation
and I'm confused now.
Well, I mean, I think this is the least clear of all of them.
And this is probably the place where I agree most with Dan.
Right.
Just like, yeah, just write simple code, right?
Like it really isn't any more...
There's not much more to it than that.
Now, you know, that's my personal opinion.
But I think especially for all the reasons that you were just talking about of like in the C++ world, there's lots of other ways to solve that problem rather than creating higher-level interfaces.
You know, templating, for example, I think could be potentially used there.
But, you know, this is the thing where I think I agree the most with Dan, and I say, okay, yeah, just write simple code.
So, for me, the solid principles are are like, they start off real strong.
You know, S, single responsibility.
Yeah, totally get that.
I use that all the time.
Makes total sense.
Open close principle.
Yeah, in certain contexts, that's really kind of valuable.
LISCOP substitution may have been a prank.
Interface segregation, only useful in very specific situations
and I don't really find myself in situations anymore and it Benzene
version it's like yeah I just don't care so really the solid principles should
just be like so yep and even the O is kind of like I sort of yeah 90% mark
right the regular expression of this acronym yeah this is I going to say this is why we don't have books
but you do have books.
I don't believe you've backed up any of your books
with complicated acronyms.
No.
I do have one actually.
I do.
I have one.
The fire principles?
The fire attributes I guess?
I did do that. I mean as a consultant you have to.
Literally it's your job. It's in the job description your job is to come up it's in the job description you have
to come up with the pithy you're getting people to remember it right and you know people don't
remember what you do and they don't remember what you say they only remember how you make them feel
and when you make programmers go ah then they feel something right otherwise they're just
they don't feel anything so you have to drive it home with those sort of really terrible puns.
That's the key to teaching programmers.
Oh, that was the sound of a pun, right?
Because I was going to say, most developers I meet do make that sound,
but then usually it's frustration at me and something I've done.
No.
Well, that is, you know, happy sailors complain.
Have you heard that?
No.
Yeah.
If your sailors are complaining
they're happy and if they're silent then you're in a lot of trouble there's about to be a mutiny
but as long as they're complaining you know they're happy that's yeah right yeah yeah that's
a i i think that does does make sense sadly that's the programmer mindset i've seen many many many
times and had many many many times um so had many, many, many times.
So, yeah.
So, that's, I mean, you know, that's sort of the quick run through of Solid.
Of what Solid is.
And that's my take on them.
And I think we've done, we've mentioned a few of the things that Dan brought up in his article along the way.
And, I mean, I, basically because, again, my understanding of the Solid principles wasn't very strong.
Wasn't very solid. Other than like the S. Wasn't very strong. It wasn't very solid.
Yeah.
Wow.
There you are.
Now I'll remember because this is how you made me feel.
No, because my understanding wasn't that good.
The article made sense to me just of its own because it was making good points.
But I think I've got a better understanding now.
But were there
any parts of the article of dan's article that we haven't covered possibly i read it like earlier
today yeah we don't have to read through the whole thing it was more a question of me wanting to pick
your brains about what solid was so that i could have a decent understanding because i think i've
i've long had this feeling that i i I'm not as real a programmer as most people
because I spend most of my time in the weeds down in the lower levels of the technology stack.
And there you've got a free pass for a lot of the good design principles
all in the name of performance.
Yeah, yeah, yeah, we don't use this because that would be too slow.
And I mean, I'm spending more and more of my time realizing that the things that i say
like that are not actually true anymore but it has definitely given me about a 15 year free pass
out of like good solid engineering principles like you know high level engineering principles
so i'm i suppose i'm a little bit um behind and i'm now just abusing the fact that we have a podcast to learn from you, which doesn't seem like the worst idea for me personally.
Well, I mean, I think a question you could ask are, in general, are programming principles a good idea at all? Right? Like, do they hold up over time? Is this a good way to teach people? Is this a good way to mentor people? Is to have a set of principles that you say, like, this is what represents good software design. And I think I could maybe argue that the answer to that is no. I could definitely argue that the answer is yes. I mean, I professionally argued that the answer to that is yes.
But then your paycheck was somewhat independent of people believing right right like
oh no really okay well then we don't need to hire you and that's the end of this conversation right
um and i i mean i can i can argue i think i can argue both sides because i can definitely see
merit to both sides right um getting back to the whole like so there's there is a technique this
is not a principle this is a technique that i have used quite a bit when I am trying to teach people how to mentor.
So mentoring mentors.
Whoa.
And it's called shuhari.
And it comes from – I think it comes from a martial art.
I'm actually not sure on the entomology of this word or this phrase.
Entomology, the study of insects.
I think, etymology.
Etymology, yeah.
You're not sure about these insects.
I'm sure about the
etymology of entomology.
So,
etymology.
And so, Shu Hari is this
basically three-phase model
of mentoring where you give
people, Shu is the first phase
and you give people a rote series of steps to follow.
So you say, do these things. Ha is the second
phase where you start to help them, they start to see
patterns and you start to help develop patterns and you name the patterns.
And literally in software engineering we've had the patterns movement and other principles like this,
where you say, you know, these are things that tend to happen. And this is what we call it when
that happens, right? And then people can start to mix and match those patterns and they see the
world in patterns and they start to recognize them. And then re is when you sort of move beyond
that and you start focusing on outcomes, right?
Like you don't worry about the patterns. You just think about this is what I want to achieve
and you have enough experience and knowledge to just know how to achieve it, right?
Yeah.
And the interesting thing about shuhari is that it is a shu level technique.
Follow these steps and you will achieve this outcome, right? So, when I'm teaching people
how to mentor, the first thing I usually teach them is shuhari, right?
The shu of the shuhari.
The shu of the shuhari, right?
And so that second phase,
I think is where these kinds of principles
have the most value, right?
Because you're trying to get people to move beyond
the sort of rote copying of do this, do this, do this, do this, to starting to see what's going on and see the patterns.
And being able to name them lets you talk about them.
Because if you don't give them names, then it's, remember that thing that we did the one time with the bubble?
Yeah, yeah, yeah.
Your 15 minutes of the conversation before you got to the point.
You know, the Gang of Four Patterns book gave me a vocabulary to describe, even if we weren't using them very often.
But you could just say, hey, you know you know that thing that's a flyweight and then you could have a conversation
about why it was a flyweight and yeah super useful but yeah no this makes a lot of sense
yeah so so like once you have those names you know and it's like an electrical engineering
you have a resistor you have a capacitor you have a transistor right like you you don't have to
describe the properties of a capacitor every time you want to talk about you know and indeed when you're like doing like
ee 101 type stuff you know you're just like yes you put a resistor it's always a 220 ohm resistor
next to the led because you know and it limits the current and then you just move on with it
and you say you just do that yeah forget about it in fact you'll see i've seen some people online
with like they just make these these leds that have the 220 ohm resistor like like on the leg of the
of the led so they could just plug them into their but never blow them up right yeah and then later
on you're like well what's the principle of that well it'll explode if you put the full power
current through it and later on you're like well i know i you know i understand what i'm trying to
achieve i'm just gonna i don't even need the light So I don't need the resistor and I don't need the LED.
I'm going to lick my finger and put it on the... Yeah, okay, that's on now.
That's it.
Whatever.
Exactly, yes.
Not the best analogy.
Yeah.
Yeah, so at each phase there, you can kind of get stuck in a little bit of a cargo cult,
right?
Where if you're just following a pattern and you never really...
Or you're following the steps and you never...
If, for example, somebody's livelihood depends you um following the things that they're saying then one might argue that
there's a certain like not so much a cargo cult as like a willful uh recycling of ideas which i
know we've got ideas you know we've talked before about how we do this um this process of determining
what we're going to talk about we've got some of those things on our
list so i don't want to go i don't want to go into that now we've got not enough time left to start
on that whole world yeah yeah but but yeah i mean so there's these are like the eddy currents that
keep you in one of your little things because you know there's there's you know there are there
there's the agile world that says no this is how we do things around here and there's a benefit to
being able to talk about it.
But then, as you say, it could be a limitation.
Right.
There's lots of parallels with lots of things.
And a lot of it comes from expertise, right?
Like, if you are observing something that somebody does and you start to hear them talk about things in terms of patterns, but you don't understand what those patterns are, you can actually subtly reinforce that sort of pattern style thinking
because that's the only mode that you have to communicate with them.
Right?
You say like, oh, shouldn't we add a resistor to the LED?
I don't know anything about resistors or LEDs,
but that worked at my last job.
Right?
Yeah, you're like, oh, no.
Yeah.
Like unless you really understand why it is that you're doing that,
then it can be the organizations can
reinforce this, you know, managers can reinforce this, all kinds of things can sort of, you know,
standards committees and certifications and all of these, are you a scrum certified, blah, blah,
blah, because you do these steps and those steps and this steps, right? Like, all of those things
can be reinforcing to sort of keep people to sort of hold them back and like never let them progress to the point where they are letting go of the patterns and just focusing on outcomes.
On the outcome.
Yeah, that's a really powerful way of thinking about it.
And again, it's not like this is a bad thing necessarily.
It's a natural progression.
Yes.
I mean, I'm just thinking about silly things like learning to drive.
You get in the car and your driving instructor says do these
things question not why we're doing them you know one day you'll you'll do you'll realize why and i
mean particularly uh in in the uk when i was was growing up actually one of my best friends was my
his father was a driving instructor and there was all these things that we would have to do like
passing plates as you turn the steering wheel you always have to have one hand on the steering wheel
which means that you're essentially got your hands at the
like 10 o'clock and two o'clock position and then you kind of move up and then you pass it and then
you put your hands back down and you're kind of like shuffling around to turn and then of course
he would drive me home or he'd drive us home me and my friend home and he would like have one hand
on the top of the thing spinning it around with his palm or letting go of it in time like i'm like
clive what are you doing he's like yeah yeah yeah forget what this is we teach you these things because that's what we're expected
to teach you and that's what's going to pass the test and there is foundation in why there's a
reason in why of those things right it's because if you're if you are uncertain of the road that
you're driving on you hit a pothole and you haven't got your hand both hands on the wheel
or at least one hand strongly on the wheel then the car could jump and disappear off and if you're traveling at 40 miles
an hour and you're not able to keep it straight you're in trouble so we just teach you this thing
later on you'll be changing your shoes in the car while you're late for a function while holding the
wheel with your knees and pulling the choke out in the manual car to keep the you know as a poor man's yeah i mean
friends of mine have done these such things right so you know but you you learn to judge the the
situation based on the experience and what the outcome is which is hopefully not your
impending crashing into a tree and you're you're right but so that that makes sense to me you know
and again when you get like somebody coming new into a team
you're like hey this is how we do everything and then hopefully you have a period of time where
they they they say all right we'll just go along with what you're saying for now and then i'll get
a feel for the why's which may not be as easy to communicate then we can have a discussion about
the always observe that you do these things together why is that oh yeah we've had this
problem once where we deploy and then we had to back it out so we always had to make sure that we can
do this. So every time you do a deploy, you always immediately
wind it back just to prove to yourself that you can do it
or whatever the technique is.
What if we can develop commons another way?
And then so on and so forth. I see. It makes perfect sense
to me. I like that.
So yeah, the solid principles
are a way, especially
if you're operating in that sort of object
oriented world. And honestly, I kind of feel like they almost apply more in Java than they do in C++ in that sort of object-oriented world, and honestly,
I kind of feel like they almost apply more in Java than they do in C++.
Like, they sort of came out of the 90s, and I feel like, I mean, obviously, Bob and those
guys are very well-experienced C++ programmers, so it's not like I'm saying that they're,
you know, coming from a place of ignorance on this.
No, of course, you know, I, I, I maybe would recharacterize this as it's in a lot of ways, easier to apply those principles
as written in Java, right? Yes. Um, like it's much clearer and, you know, maybe that's a,
a nod to Java and it's, it's, you know, was based on the design of, of things that at least at the
time were, were novel and good, but it, you But, you know, it's something where unless you're doing that particular style of software development,
you know, it's just so-so.
Ha-ha!
I don't know.
Well, I mean, that seems like we can't beat that now.
A mic drop?
This is definitely a mic wallop as i keep
walloping my mic on this funny stand you can probably hear yeah no that's yeah that's awesome
um yeah well now i know what the solid principles are and i know that i can disregard the the lid
drop the lid take the lid off solid we can make some more puns um yeah right and we know that the
open closed principle or open closed principle really just means write easy to understand code that's easy to change.
And the single responsibility principle, I think, what you precede as write easy to understand code.
So what I'm really hearing is –
Maybe a little more nuanced than that.
No.
It's just, I mean, write straightforward code.
And that's almost always the right thing to do, right?
If you're faced up against a decision, it's like, which one's the easier one to do?
And most of the time, it's the easier thing to do.
If I were to quote Bob, I would say, yes, write simple code all the time.
That is what you should do.
The solid principles can be a way to achieve that if you know how to apply them correctly.
That sounds like a great way of
explaining it and a great way to finish the episode too sounds good to me so catch you next time yep
you've been listening to two's compliment a programming podcast by Ben Rady and Matt Godwald.
Find the show transcript and notes at twoscompliment.org.
Contact us on Twitter at twoscp, that's at T-W-O-S-C-P.
Theme music by Inverse Phase.