CppCast - SOLID Design Principles
Episode Date: January 28, 2021Rob and Jason are joined by Klaus Iglberger. They first talk about changes to make the Win32 API more accessible, some C++20 coroutine examples and ISO news. Then they talk to Klaus Iglberger about th...e SOLID design principles, why they still matter and what C++ developers should know about them. News Making Win32 APIs More Accessible to More Languages Motivated Examples for coroutines January 2021 ISO Mailing Links Breaking Dependencies: The SOLID Principles - Klaus Iglberger - CppCon 2020 Meeting C++ Training: Modern C++ Design Patterns CppCon 2020: Modern C++ Design Patterns Cpp On Sea: Modern C++ Design Patterns YOW! 2013 Kevlin Henney - The SOLID Design Principles Deconstructed Sponsors Visual Assist
Transcript
Discussion (0)
Episode 284 of CBBCast with guest Klaus Igleberger, recorded January 27th, 2021.
This episode of CBBCast is sponsored by Visual Assist, the well-known productivity extensions for Visual Studio.
Visual Assist speeds up development with features like smart navigation, code inspection and suggestions,
powerful refactoring commands, and a whole lot more, even spell checking and comments.
Start your free trial at wholetomato.com.
In this episode, we discuss coroutine examples and some ISO papers.
Then we talk to Klaus Igleberger.
Klaus talks to us about the solid design principles. Welcome to episode 284 of CppCast, the first podcast for C++ developers by C++ developers.
I'm your host, Rob Irving,
joined by my co-host, Jason Turner. Jason, how are you doing today?
All right, Rob, how are you doing?
Doing okay. I don't think I have too much news to share this week. How about you?
Just a funny aside, you can see I've got this castle behind me, which is uh ellie and donnan castle in scotland and um apparently uh claire mcgray
noticed this on the show before yeah on one of the recent videos that was posted on youtube
and uh i'm aware that this is a castle it's associated with the mckenzie's because that
is something to do with my wife's family and that's one reason we went there this is a picture
that my wife actually took
and claire uh pointed out that it's actually the mcrae mckenzie castle apparently and um so she
was thought very interesting that the castle was there that's interesting yeah very cool okay well
at the top of every episode i'd like to read a piece of feedback uh this week we got a comment from an episode on YouTube. This is our end of year
2020 episode and Falcon wrote, regarding scripting, I'd be interested to see what either of you think
about TypeScript on Node or Deno. It's got a ton of advantages of the NPM ecosystem, rich set of
packages, convenience of installing, etc. And the language itself has a really good set of features.
We've certainly talked about TypeScript several times,
including with your cousin who worked on it, but I'm not familiar with TypeScript being used in other languages.
Well, Node is just a JavaScript engine.
Right, right.
What is Deno?
I have no idea what Deno is.
No idea.
Does our guest know?
He's smiling.
No.
I don't know too okay no but i'm i'm gonna i'm gonna just say i'm fully on board if you're doing javascript stuff with node go ahead
use typescript right because that gives you an extra level of protection i guess or assurance
that your code is correct okay well we'd love to hear your thoughts about the show you can always
reach out to us on facebook twitter or emails at email us at feedback.cppcast.com.
Don't forget to leave us a review on iTunes or subscribe on YouTube.
Joining us today is Klaus Eagleberger.
Klaus is a freelancing C++ trainer and consultant.
He has finished his PhD in computer science in 2010 and since then is focused on large-scale C++ software design.
He shares his experience in popular advanced C++ courses
around the world, mainly in Germany, but also the EU and US.
Additionally, he is the initiator and lead designer
of the Blaze C++ Math Library
and one of the organizers of the Munich C++ User Group.
Klaus, welcome back to the show.
Hi, thanks for having me back.
It feels really good to be back.
I can't remember if I asked you about this last time we had you on,
but did you specialize in anything in particular for your PhD?
So my PhD was about particle simulations in particular,
but it was mostly about high parallelization.
So the biggest machine at the time was,
so at least in Germany,
was about roughly 300,000 cores,
which I was able to use at least once.
So, yeah.
Nice.
Very cool.
Did you simulate anything interesting in your experiments there?
So the attempt was to simulate as many particles as possible within a fluid.
And so I cannot claim that it was particularly interesting.
It was a scaling experiment.
But later this was used to do something more valuable, I believe.
That kind of thing is always fun, though, when you've made a visualization of the simulation
of the fluid particles or something like that. That would have been fun. Writing from 300,000
cores to files. Oh, my. Okay. Well, Klaus, we've got a couple news articles to discuss.
Feel free to comment on any of these, and we'll start talking more about the solid principles and what you've been up to, okay?
Right.
All right, so this first one we have is a post on the Windows developer blog.
And this is about making Win32 APIs more accessible to more languages. And obviously, if you're on the Windows platform,
you can access the Win32 API if you're using C or C++.
But they're trying to create new projections
to make it easier to use in C Sharp and Rust.
And also, it's kind of mentioned at the very bottom of this post,
they're going to make a modern C++ projection of the API.
So instead of using the somewhat ugly C API,
you can do it in kind of more native C++, which sounds really nice.
Rob, I feel like you're so much more connected to this kind of thing than I am. But how does
this differ from the WinRT or whatever?
I think it is based on it a lot um and you know when reading this post i definitely
uh assumed that kenny kerr who we've talked to about with uh win rt and and uh i believe the
name of that project was like modern c++ or something like that modern cpp uh i believe
he's involved with this uh maybe we should have him on to talk about it. Yeah, I don't know what else to say.
Okay. Klaus, do you have any
thoughts on this one? So I definitely
like the idea, and I do like that they
also used a community
effort. A couple of people have done this
on their own before.
Microsoft is basically collecting this wisdom
and trying to move forward, which I feel
is indeed a very good thing. I did not
use the DevWin API personally, so for me it's a very good thing. I did not use the Divi API personally.
So for me, it's not a direct win.
I don't know this either.
No, I haven't.
I've used it only when I have to.
Load library, for example.
I've probably used maybe all told a dozen Win32 API functions.
They mentioned C-sharp here
and having to write P invoke calls by hand if you want to use Win32 APIs there.
And I've definitely done that a couple times.
So being able to access those APIs natively with C Sharp would be very nice.
Okay, next thing we have is a post on CPP subreddit.
And this is, do people have some motivating examples for coroutines?
Jason, you want to go over some of these well yeah i mean i i personally like i'm constantly having people ask me like can you do an
episode about co-routines on c++ weekly and i you know i know i've mentioned it on this show in the
past that the fact that we don't have a standard library for co-routines is a little frustrating
but anyhow there's a couple of examples here,
like someone who wrote a Game Boy emulator
that uses coroutines and awaitable types.
And that's something that Matt Godbolt and I
did a live stream about discussing
what the possibilities were there.
We didn't get very far.
So for people that were interested,
you might check that out.
Very cool.
Yeah, so this is also something
I get in my training classes a lot.
People are asking about real examples,
not just the toy examples that you usually see.
So this was pretty interesting.
And indeed, they gave me a thing struck out.
There's a few examples in here that I have to agree with
some of the other commenters that I'm like,
yeah, I'm pretty sure you could just do that with a future.
Or not, I mean, a promise.
I mean, not, a promise. I mean,
not necessarily a future, like,
uh,
you don't need a full,
the full co-routine stack here for this example,
but,
um,
I don't know.
Okay.
And last thing we have is the first ISO C++ mailing of 2021,
uh,
the January mailing.
And,
uh,
a couple of things, uh things stood out to me here.
First of all, right at the top is introducing Stood Colony to the Standard Library.
And that one just made me think of, you know, how long we've been doing this show.
Because I went back and we talked to Matt Bentley.
I think it was episode 65 about the PLF uh library he wrote and the the colony container and i don't
recall if he was trying to standardize it as far back as when we recorded that episode oh no he was
definitely talking about it if you look at this this is revision 12 of this paper it's been going
on for a while it's been discussed a lot in the in the mailing lists. This was one of the hottest topics.
Is it coming to fruition?
Do we think it's going to make it in sometime soon?
That I don't know, of course.
No, no, no.
I spent so much time with PMR and custom allocation stuff
on the series that I did on my YouTube videos
that I have thought back to these colony containers and
wondered, could you get basically the exact same thing by just using a monotonic buffer resource
behind your list or whatever? And I don't know if that's the case. If that is the case, then I
expect someone on the committee would have brought that up at this point. And I should go back and review these things more in depth.
Another interesting one I saw.
Go ahead.
Sorry.
No, go ahead.
So what struck my eye was the problems with cBegin.
I have to admit I wasn't aware of that.
That is a paper by Nicolae Iositis, so P20276.
That I found pretty fascinating. A little detail, but interesting how easily things can go wrong.
So apparently C begin did not work well in combination with span.
So the first fix was to remove the C begin and C end, also a number of functions from span,
which, however, did not really solve the problem.
It even made it worse.
Nikolai is now arguing to put them back and to
really fix the problem. That was a
fascinating read for me.
I'll have to check that out too.
It was fascinating
that he found this out so late
that this little detail apparently
slipped through everybody's
attention. Seems to be that that happens.
That's surprisingly awesome. Yeah, unfortunately.
Anything else you want to mention here, Jason?
Yeah, the changing scope for Lambda trailing return types from Barry,
P2036R1, struck me as interesting,
because if you've spent as much time with Lambdas as I have,
you would go, oh, well, of course that doesn't work,
but he's trying to fix it so that you could and the idea is to be able to refer to
a capture name in the trailing return type currently they're in completely different
scopes because a capture isn't part of the function signature at all it's part of the body
of the lambda so for it to be referenceable from the trailing
return type, in some ways doesn't make sense, but in other ways, it's what people would expect to
be able to do. I get the idea. Interesting. Okay. Well, Klaus, let's start talking about
solid. So if you've been programming for a while, you've probably heard of the solid principles. But you gave a really nice talk at CppCon this past year, going into each of the different solid principles in some detail.
Could you maybe start off by giving us a brief overview of them?
All right.
So I hope I don't make this another one-hour talk.
But perhaps a brief overview for those who have not heard about them before.
So Solid is an abbreviation for five design principles.
So initially, they're pretty old to some extent.
Some were formulated in 1988, at least conceptually, but they were put together in 2000 by Robert
Martin, who decided that for him personally, these were the five most important object-oriented
design principles.
This is how they are also listed at Wikipedia
as object-oriented design principles.
He did not call them SOLID at this time.
I think four years later, approximately 2004,
Michael Feathers realized that S-O-L-D-I could be made into SOLID.
And so this is where the SOLID acronym comes from.
So the first letter, this S, is for the single responsibility principle. A principle that
essentially tells you that change is important and you should design for change. You should
design such that you can change things in one place, that things are changed for one reason. Also, then the second letter is for the so-called open-close principle, which is,
well, the name does not reveal it so much in this case, which is about how to
extend things more easily. You should design such that things are easy to
extend in the direction that they want to go. Okay, I'm sure we're talking about
a couple of examples later.
Sure. Then the L, the Liskov substitution principle, is a little focused on, well,
substitutability. What is a good substitute? How should the substitute behave in a certain environment? What is expected behavior? Then we have the I, so-called interface segregation
principle, the one that people usually tend to forget because it apparently is the least important.
From a personal perspective, it is indeed a special case of the first one, but it is focused on interfaces.
It tries to decouple interfaces or give advice on how to decouple interfaces.
And the last one, the dependency inversion principle, is about steering dependencies the right way so that
you can really create proper architectures, proper design where some things depend on
other things and not the other way around if it is the way you want to design it.
Okay, the short introduction, the quick walkthrough.
I decided to give it a try at CppCon. I actually
have to admit, I did not expect that this talk would be accepted. I was expecting that
people would say that this is too old, this is known, but a lot of reviewers liked the
idea. So within 60 minutes, tough timeframe in this case, I tried to really give
examples for all of these five principles. Why are they important? Which situations go wrong if you
don't adhere to them? So I was actually pretty happy that it was accepted. I was actually hoping
even that it would be taken for the back to basics track. I wanted to make it a beginner-friendly
talk, but well, Arthur didn't like it so much, apparently.
There were so many other talks anyway.
Good talk, so.
Arthur's the primary organizer of the Back to the Basics track, huh?
Correct, yeah.
He basically tells us which talks go in and which do not.
My feeling, probably he's not the only one who has a final say.
But yeah.
You and I both had talks in the 2019 back to the basics track, I believe.
Okay.
Correct.
Yeah.
Now I had one other talk in there as well, but the solid talk was extra.
Yeah.
I find this just in general, these engineering design kind of principles.
When I do training i have
people ask me oh can you do a class on you know basically the kind of thing you're talking about
and i'm like no i i can i can teach you how to understand c++ better i am not the right person
to come and do training about how to design your architecture better oh this is good to know now i have something where i can say if you need that ask me
because i'm truly focusing on design issues more than on the c plus language issues
so perhaps this is indeed a good combination they can hire us in in sequence perfect that sounds
great actually yeah let's do that so indeed in a lot of training classes, I talk about solid too.
But then, of course, I give a lot more examples on how code should be structured.
Design patterns are also something I tend to talk about a lot nowadays.
And this is where I apply them.
What works? What does not work?
Why does that work and this does not?
Very often you can use these solid principles to give them a feeling why something does not work and another solution works better.
Okay, so we're going a little off the plan here. Since you just mentioned design patterns,
are they still relevant? Are they relevant to C++? What does the modern programmer need to
know about design patterns?
So my personal opinion, of course, is they are relevant and surprisingly relevant.
Just perhaps a teaser for the training class.
I know we shouldn't do too much teasing,
but type erasure is essentially just a combination of four classic design patterns.
And it works pretty well because all these properties of these design patterns are it works pretty pretty well because all these properties
of these design patterns are just combined. Good ideas combined should give
you something even better. I believe it's relevant because of the
terminology. First off you should have an idea what what probably are trying to
solve if you talk about a visitor, if you're talking about an observer, a strategy. And so some people argue this is ancient, this is not needed anymore. But I think
this is just again about managing dependencies properly. And this is as necessary as it was 20
years ago, or 25 years ago. So the Goff book was published in 1995.
That's the Gang of the gang of four that's
what you're getting a four book yeah yeah the classic design patterns book i've uh it's been
on my to-do list for i would say at least 11 years to read one of the design pattern books and i have
i have not yet done that okay would you recommend that i still go back and read the classic book or
maybe one of the newer takes on these things?
I don't know, headfirst design patterns or one of these lighter weight versions.
Yeah, okay.
That's a problem.
Lightweight.
The classic book is not particularly lightweight.
Probably you're pretty bored halfway through.
It's a very formal description.
And the coding examples, you would not like them.
They're totally
out of date.
Okay.
There is not a lot of new
books, though, that really
go through all of them and explain them
in this formal way. There's one book by
Dimitri Nestruk
who tries to give more modern
examples. This may be something that you can
choose. It has received mixed reviews on Amazon, so some people like it, some people don't.
If you read it, you can of course make up your own choice whether this is something you like.
There's a hands-on design patterns book by... and I forgot the name, sorry, it comes up too many a second, which is also good,
but it's bigger and there's a lot of content that you already know, so language-specific things.
But unfortunately there's not a lot of literature on design patterns anymore,
something that formally introduces them and perhaps uses new examples
to, as a modern C++ examples to give them a real meaning.
I found the Hands-on Design Patterns book, I think the C++ one, although I have
to say this website that I found it on makes it very difficult to figure out who is the
actual author, unfortunately. Okay, if i turn around i can um fit
up because of course okay sorry fitter and it looks like there's various versions of these
there's the hands-on design patterns with delphi which is unlikely to be applicable to most of our
listeners i believe and then hands-on design patterns with C++ is assuming the one you're referring to.
Correct.
Okay.
Yeah.
Going back to Solid, you mentioned how Robert Martin came up with these like 20 years ago
as being for object-oriented programming.
Do they only really apply to object-oriented programming,
or do they apply to other styles of programming, in your opinion?
In my opinion, and also luckily the opinion of a couple of other people,
they're completely paradigmagnostic.
So you can use them for object-oriented programming
just as well as functional and generic programming,
because it's mainly about dependencies.
And this is a problem that you have in all kinds of programming.
Of course, sometimes it needs a little different explanation how they apply.
This is exactly what I tried in the talk as well.
So I usually try to show some object oriented stuff, the classic stuff that people understand
more quickly and something from the standard library where this principle is applied.
So, just perhaps as one example, I think I used a copy function, so standard copy,
to explain that this is a dependency inverted function too.
Of course, it has nothing to do with object-oriented programming, not really,
but the idea that you depend on copy and not copy depends on
you is built into this function too by means of the template arguments. So the copy function
itself defines the requirements, defines what you have to deliver. And so copy doesn't depend
on you, but you depend on copy. It's just sound library design because of course if you write a
library you cannot depend on somebody else. You want to be independent, you
want to define your own requirements. So a concept
essentially, now C++ terminology of course, is pretty similar to what a base
class is just with static polymorphismism. So you can work with this just as well as with base classes, meaning object-oriented
programming.
So you mentioned standard copy specifically, but it sounds like those principles apply
to all of the standard algorithms?
Yeah, absolutely.
Just a specific example that I used in the talk.
Of course, the entire library is
dependency inverted in this way, making it a real library that is standing on its own
and that you have to adapt to. And similar examples can be given to all the other principles as well.
I have to admit, I don't remember exactly which examples I gave. Copy is one of my simple examples,
but you should find various examples
of dealing with these principles in the STL2.
Reminds me of a talk David Stone gave
at C++ Now 2015,
and he also just reiterated some of these concepts
in a talk that he gave at my meetup that I have not yet edited and put on YouTube.
So you can't go and watch it yet.
But the idea sounds like, you know, continuing along those lines of basically in his worldview,
something like a standard container like vector would have very few functions.
It only had like four functions and the rest of it would be implemented in free functions similar to copy that are decoupled, making it easier to create
standard containers than it is today. I kind of already think I like the talk.
I've not seen it, but this is my opinion too. Whereas I don't complain about standard vector.
Standard vector is actually fine, although it has 60, 70, I don't know, member functions, quite a lot.
Those are constructors.
Probably, yeah.
And there's multiple overloads of begin and end, of course,
so everything sums up.
But still, I believe Standard Vector is very much focused on managing a dynamic array
with very little functionality that is just convenience.
So, for instance, pushback is convenience for insert, but with the additional benefit of a different exception safety guarantee.
And so there is a very important implementation difference that of course is important. So I think
this is fine. As a counter example, standard string probably would not satisfy this single
responsibility principle. Hey, we got like five more member functions in C++20.
And it keeps growing.
It has to because of the interface changes.
And it will never change.
So standard string comes with everything.
All kinds of manipulator functions, substring functions, all kinds of algorithms, find, etc.,
which, of course, are a little more convenient than using the STL algorithms, a little more direct, perhaps some better names.
But most of them could indeed be implemented separately outside the class, couple less, be more generic.
So this class could be leaner, less coupled. But of course, we cannot change
it today anymore. Yeah. And I think this is what David probably talks about too. Probably
you can decouple quite aggressively if you really focus on the essential interface, nothing
more. I'm kind of curious what other parts of the standard library break these principles other than string.
Okay, I did not do a detailed analysis.
No, no, no. Okay.
I do agree that a standard function could have been leaner,
but this is something that, of course, most people nowadays agree to.
But no, I did not do a detailed analysis of of the SL with regard to the solid principles.
No.
Yeah, standard function, I think, to be fair to the standards committee, along with standard bind,
where they were standardized at a difficult time as we were trying to understand what modern C++ was supposed to look like.
What is C++11 actually bringing to the table?
Those kinds of questions.
Yeah.
Some day we'll probably have
a potentially half-successor
and a function
too, or somebody
proposed, I heard this recently,
a trampoline,
because the not function acts like
a trampoline, a call to some other function um so i think there's potential to update this eventually
yeah there's yeah and function view i think was probably similar to the trampoline would sound
like uh oh yeah yeah yeah i want to interrupt the discussion for just a moment to bring a word from
our sponsor visual assist visual assist is used by serious C++ developers across the world. It's got great code generation. Do you
need to implement methods from an interface? What about changing a pointer to a smart pointer,
even an Unreal Engine smart pointer? Adding a symbol you've typed but haven't declared?
Visual Assist will do these and much more. Plus refactorings, more powerful than the ones
included in Visual C++. Or detecting errors in code and suggesting useful corrections,
or navigation, helping you move anywhere in your code and open or locate what you need,
or even the debug extensions.
Visual Assist is written by C++ developers for C++ developers.
It includes everything you need and nothing you don't.
It has a low UI philosophy.
It won't take over your IDE, but will show up when useful.
It's there to help, not to advertise itself.
Visual Assist is relied on by the developers
building software you've used. Whether
that's office suites, operating systems, or
games, software you use was built
with Visual Assist. Get the same tooling
for your own development. Visual Assist
supports Unreal Engine 4 and many versions
of Visual Studio, including VS
2019 and Community. Get it
at wholetomato.com.
What do you think
C++ programmers should really
make sure they understand
with solid principles?
If you're new to C++ or new to programming in general,
what should you make sure you understand
from these?
I think it definitely pays off
to get an understanding
why they are considered
important design principles.
As soon as you're starting
to write bigger software
and not just a couple of thousand lines of code,
but large scale stuff,
you will always have to face
the other problem of dependencies.
You change one thing,
everything recompiles
and you want to change one thing and you have to touch a lot of dependencies. You change one thing, everything recompiles.
And you want to change one thing and you have to touch a lot of places.
And as soon as you hit this certain threshold,
and I think Jason defined this
to be larger than 20,000 lines of code
because your ChaiScript is smaller.
As soon as you hit this threshold,
this suddenly definitely starts to matter.
And it also starts to matter if you're working in a team and everybody is working only on a subset of things.
And so I do think that it pays off to have a pretty good idea of the basic ideas behind SOLID.
So why is it good to pay attention to the single responsibility principle?
Why should concerns be separated?
Why should cohesive things go together and other things go separate?
Why should I really think hard about an extendable interface?
I should think about what do I want to extend in future and apply this open-close
principle. So this is why I think this might be valuable. It's not something that you use with
every single line that you write. Does this adhere to SOLID? Does this adhere to OCP? I don't think
so. But it's more this feeling of realizing that dependency can hurt you pretty
badly. And this is what I see when I do consulting or also training classes or talk to people.
Indeed, the major pain points are things that are too tightly coupled, things that cannot be
changed easily anymore. And then they're not documented and badly tested also sometimes. And then, well, people just are not really happy anymore.
Sounds like a great situation.
A bunch of tightly coupled spaghetti code 40,000-line functions that aren't tested.
I've not seen a 40,000-line function yet.
I can show you one if you'd like to see one.
Oh, okay.
I've seen classes that I have the this kind of
size here actually no I'm sorry I can't show you a 40,000 line I believe the longest I can show you
right now is a 22,000 line function okay but a factor of two what is a factor of two right
eventually people say oh it's it's it's large it's large Okay, so say you have this 40,000-line file with a 22,000-line function in it,
and basically none of these solid principles have been applied.
Yeah.
And feel free to say, well, you have to take my class to get more information.
No, no, no.
How do we get started on trying to fix these problems?
So if it's really a 40,000-line function, it's probably a long and painful process.
Probably shouldn't get there in the first place.
But usually the advice is to start separating concerns.
To really think about why is this function so long?
Is it really something that focuses on one issue? And I would slowly but steadily tear these
things apart. One of the things that you can likely do in this kind of function is to use
Wri a little more often. Very likely this is also dealing with memory management and all these kinds
of things. This is why it gets so long. Probably also a lot of error
checking etc. If all of this stuff is separated out, separate functions, functionality, perhaps even separate modules, this makes things easier already. And of course the hardest part is then
understanding what are the subparts that I put together? What are the individual functions that I could extract?
It definitely isn't an easy job. Oh no, definitely not. It takes some time. Usually, however,
it's not these long functions. Very often it's just bugs that you encounter, bugs that
sometimes are just based on a misunderstanding. Very often, interestingly, however,
the bug, as a source,
the bug has somehow mixed responsibilities.
Something does two things.
I change one thing in some update and broke something else.
It happens indeed surprisingly often.
And then the real fix is not to just
change the line of code
that broke, but to separate concerns in order to make sure that in the future
this kind of problem cannot occur again. The real problem now
is that this takes definitely more work, definitely more time, and so probably
it's not done right away. This is how these 40,000 line code functions come to exist.
I just need another if here.
It'll be fine.
Yeah, exactly.
People follow example.
People don't want to invest so much time.
Sometimes it's true that they don't have the time.
So things grow instead of things are separated
to create new building blocks that they can reuse in a lot of places.
So if someone's going to hire you to come in and do training or consultation,
why would you argue that it is worth spending the time to learn these things and to fix the problems the right way today?
Because I'm pretty much convinced that good code is cheap code.
Very often people are concerned about time and money,
at least management is eventually.
And if you spend a little time upfront
to keep the quality high,
you'll have so much less problems later
and will save so much time and money
that people will just be so much happier.
That's why I definitely feel there is there's a huge value
in a real life in a real environment of course it's not that easy i totally admit but having
these things in the back of your mind perhaps helps you to sometimes at least do the right thing
even if it's slower yeah i've seen a lot of things by now.
Okay, so you mentioned several times that you're happier this way. Have you actually directly observed this,
that developers that are working on the SpaghettiCode codebases
are not as satisfied in their job?
I did actually experience this firsthand.
So I've worked in a couple of teams by now,
and I think there is really a difference.
Some people are just doing their job because they have to.
They're not unhappy, but they do know that it's not a perfect situation.
And I've seen the other side as well, where people are really investing a lot of time into refactoring and writing tests
and also keeping their developers on a very high C++ level.
I feel the atmosphere is just better.
People are also much more likely to help each other
because they have the time to do so.
It's a more lively group,
more lively interaction between people.
Sorry. Do you ever run into any like misconceptions that programmers might have or hesitant to start you know spending
the time and investing in learning and applying these design principles oh there is indeed a
couple of misconceptions um the first thing that i think the hardest of these five principles is the first one,
the single responsibility principle. Because commonly this is understood as, well, everything
should have one responsibility. And even simplified, everything should do just one thing.
And it is really hard to apply to anything. What is doing one thing? What does this truly mean?
Does standard vector do one thing?
Yes or no?
I really couldn't answer because I don't know what this one thing is.
And if you really think along these lines, it really is very hard to apply.
If you think about change a little more, this is what I try to also show in this talk.
If you try to think about why would I change this?
What does this represent?
Suddenly becomes easier. Easy to
apply, easy to reason about. Also, I said standard vector represents everything that you need to
manage a dynamic piece of memory, a dynamic array. Standard string represents something similar and
a lot more things that you can do, a lot of more operations. Also, is a function that
does something and does logging, is this okay or is it not? Because it does two things. Well,
it is okay as long as this one function does not implement all the details for logging, etc. If
this is just using other functionality, the responsibility, the task of this function is just to draw these things together to create something bigger.
That is reasonable.
You would only change it if you wanted to change the sequence of operations, for instance.
That is, I think, something that keeps people from really getting the value of this single responsibility principle.
I've seen a talk, okay, I can mention a talk by Kevlin Henney, who really tried in his talk to
destroy this, the solid principles, except for the first one, the single responsibility principle,
because he did not really believe in, interpreted them differently and argued that this is, that this makes sense. Okay,
my opinion is that definitely do make sense, especially since he's referring very to the
first formulation of these principles. And I believe since then they have evolved, we
now find them to be much wider in applicability. So, okay, my personal opinion. Then some people just feel
they're old, not necessary anymore. This is something that, of course, you can understand.
But as I said, dependencies is something that is virtually present everywhere. So I don't think
they grow old. And also, the other thing that is hard to understand is this dependency inversion principle.
The fact that I really want to turn around dependencies is very often just explained by introducing some kind of abstraction.
Or even it's just explained by, well, let's introduce a base class.
And then we have inverted dependencies.
What is often not taken into account is the fact that you also need
to assign the responsibility for this abstraction somehow, properly. I've seen this fail, so
some modularization of code, people introduced the abstractions but on the wrong side. And
to them it always felt wrong, and when we talked about this they realized, oh, if you
put them on the other side, suddenly it might actually work.
So the dependency inversion principle is probably also hard to understand.
So SRP is probably harder to apply if you imagine the wrong thing.
And the dependency inversion principle is probably harder to understand.
But, oh, okay, sorry.
No, I'm just thinking like, because yeah, I'm having a hard time thinking, okay, I believe
I have experienced what you're describing when you when you're looking at a problem
and you say, oh, this is really, really hard to implement.
It doesn't make sense.
But then if you manage to invert your thinking and say, oh, no, wait a minute, I need I'm
looking at this from the wrong direction.
If I understood correctly, you're saying people try to do the dependency inversion principle.
I'm just thinking through these things also and wondering, when you do a class, do your students bring examples and say,
this is the kind of problem that we've been trying to solve so that you can do direct examples with them?
Sometimes, not always.
It depends on the class.
But if I'm in a company, this indeed happens.
Because if I'm talking about something, sometimes they realize,
oh, if something's similar, could we talk about that?
And I feel this is the best thing that could happen
because using a concrete example is really helping them
with a specific problem.
Else, it may remain a little too abstract,
and perhaps we are not really communicating on the same page.
So examples are great.
So perhaps allow me to give you another example for this dependency inversion principle.
So you might be aware of the model view controller
architectural design pattern.
And a model, so I am now using the Wikipedia version
where the model is in the center
and you have controllers and views
that communicate with this model.
Architecturally, the goal is that the model is independent.
That model is the one thing
that does not depend on either kind of control,
so the thing that gives you some command, and the kinds of views. And I think views
is easier to understand. So you want to represent the result via HTML, via some graphics library,
different ways. The model of course should not depend on how you want to represent the result. Of course
not. And this is why the model itself should define the abstraction, how it passes information
over, which kind of structs, data sets or whatever. And the view has to just take what it is given.
So the model is in command of the abstraction. By that, it is not depending on the view.
This is why I've inverted the dependency.
The flow of information is from the model to the view, but the view depends on the model.
That's kind of the different direction.
I don't know.
This is usually where people start nodding like you just do and say, okay, I have to look this up later.
Think this through later.
It is a little harder, but really relevant if you want to decouple properly.
But you are saying that the model view controller example is a proper example of dependency inversion?
It is.
If you implement it correctly, it is a good example indeed. So if the model is in control of the abstraction, this is a dependency inversion and you have something that you can build on.
Anybody could now add a view and a model would not realize it, would not depend on it.
That's the ultimate goal, of course, extensibility by means of well let's call them plugins so do you ever see people doing
what at least what i'm inferring from what you're saying right now would be going too far and making
a generic viewer that can work with any kind of model abstraction and then they end up with
you know overly generic code and overly generic abstractions so So I cannot argue if it's overly generic or not. If you have
all the information at compile time,
go for it. Perfect.
You don't need a runtime abstraction.
You just pay attention to the same
problem. So
the model should not depend on
any kind of view. If you
achieve that, even by static
polymorphism, perfect.
So perhaps you can use um what
alexandresco suggested in his modern surplus was designed so that the book with it was published
in 2001 this policy-based design this would be a template-based approach which just works
as well right yeah you mentioned that uh kevlin henny talk where he argues against the srp uh
principle he argues against solid he does like srp though oh he likes this so this is the one
principle okay yeah correct so he completely um objects ocp he kind of argues that LSP, so that Lisk of Substitution Principle,
does make sense if you really read the original publication and the original terms that are used.
He feels like I do, that the interface segregation principle is kind of the same as SRP. I agree
here. I think it's just a very important special case, so why not mention it explicitly? And
I think he
also comes to the conclusion that dependence inversion is nothing but single responsibility
principle. This is where I feel a little different though. Okay.
I'll have to see if I can find that talk. I mean, put that one in the show notes. But
I was wondering if you had, if you're aware of any other arguments against the solid principles
or if there's any like newer design patterns
that are competing with them or anything like that unfortunately no so in this particular case
i have to say unfortunately because it would be great if there would be other things it would be
great if you would have more design principles this is to my best knowledge, this is the best we have still.
And probably this is why I still try to talk about them, or why I do talk about them.
Yeah, because I am not aware of anything better.
This is perhaps also why I feel that arguing against them is not really helping.
If you argue against them, you should propose something better, because there's so little else. I see an opportunity here for you, Klaus.
Oh, yeah. I thought about this, but no, I didn't come up with anything better.
You can come up with something. You just have to repackage it, right? So people who have
an opposition to solid, you'd be like, no, no, no, no, I don't teach
solid. I teach liquid or whatever. And it's basically the same thing, right? Just in a
different order with a couple of C++-isms and maybe some design patterns thrown in.
You know what the things that, but I'm being half serious and well, maybe three quarters serious
because you clearly have the experience and the background knowledge
to package this in a way that makes more sense to the modern C++ developer
than going back to a 20-year-old principles or whatever.
Okay. I would feel a little bad, though, if I just relabel, kind of.
No, no, don't relabel. It's a modernization of the techniques. Yeah, yeah, don't just relabel. I'm not i find a new name it's not the same thing the techniques yeah yeah
don't just relabel yeah i'm not saying steal i'm saying derive yeah yeah probably it's with
deriving being more specific perhaps giving it better names i think it's it's a naming uh problem
also their names are hard right and if you need to drop one of them because it's a duplicate then
yeah for instance. Yeah.
Yeah.
A single responsibility principle.
The name could be improved.
And then we can perhaps integrate this interface aggregation into that.
Then we only have four.
People like four better than five, probably.
Okay, I see this.
This could be something.
Yeah.
Next year.
So your CPPCon 2021 talk.
Yeah, it'll be a modern C++ architecture with whatever your new acronym is.
Yeah, I have to find a catchy one.
That's a problem.
I have to find a catchy one.
There's a bunch of four-letter words.
I'm assuming you're looking for an English word.
We have plenty of four-letter words.
Although a lot of them you don't want to use.
That is true.
And a lot of them have been taken by C++ already. You might have seen Arthur O'Dwyer's list of acronyms.
And I was really impressed on what
acronyms you already have in C++.
Really funny.
Okay.
Now I have something to do.
Yeah.
Okay.
Is there anything else you want to go over
today, Klaus, before we let you go?
You've mentioned that you do training on these design principles.
Are you giving any classes in the near future, or is this something where companies should just reach out to you?
So I will do a training in June, which has already been publicly announced on the Meeting C++ page.
It is actually about design patterns, a three-day class called Modern
C++ Design Patterns. The focus of this class is to go over not all the Gov principles but
an important selection of them, but also now definitely showing how to implement them properly.
They are not these 20-year-old code, but how do we do it today? There is a couple of very big differences
that I know people like usually.
I'll also explain type ratio for instance.
I'll explain why it is just a very clever combination
of classic design patterns.
And I actually also hope that I can do the course again
at CppCon.
So I've done this the last two years
and turned out to be pretty successful
yeah so i definitely hope that this is uh going to happen again so for our listeners who are
curious what about time zones for that meeting c++ announced or that training it's probably um
in the central european time zone um so 9 to 5 p.m. Of course, if a couple of people
from different time zones sign up,
we probably could shift that.
That shouldn't be a problem.
But it would be hard if people from India and the US
would like to join.
That would be hard.
But this is one of the big advantages
of these online trainings.
This is why I do like them.
Everybody can join.
In my CppCon training last year, I had people from Argentina, from Canada, and I believe some Eastern European country, which is a little more Eastern than Germany.
But a pretty outspread number of people.
I should, by the way, before I forget,
else Phil might be mad at me.
I also hopefully give a workshop again
at C++ on C, of course.
One of the most important workshops I do every year.
I don't know.
I've given it once last year,
and this also turned out to be a pretty successful workshop.
Has there been the dates announced for C++ on C 2021 yet?
Not yet, unfortunately.
A couple of days ago, I think he will announce something soon.
But it's not officially yet.
Okay, I was just going to feel bad if we had missed that.
Try to stay on top of these things.
No. going to feel bad if we had missed that try to stay on top of those things yeah no so the last
um post on this book uh web page was in december last year right all right well it's great having
you on the show again today klaus thank you very much for having me it was a it was a pleasure
we'll make sure we have links to all of those things on the on the website awesome all right
thanks thanks no thank you Thanks so much for listening in
as we chat about C++.
We'd love to hear
what you think of the podcast.
Please let us know
if we're discussing
the stuff you're interested in
or if you have a suggestion
for a topic,
we'd love to hear about that too.
You can email all your thoughts
to feedback at cppcast.com.
We'd also appreciate
if you can like CppCast on Facebook
and follow CppCast on Twitter.
You can also follow me at Rob W. Irving and Jason at Lefticus on Twitter. Thank you.