CppCast - SOLID Design Principles

Episode Date: January 28, 2021

Rob 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)
Starting point is 00:00:01 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.
Starting point is 00:01:24 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
Starting point is 00:02:03 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,
Starting point is 00:02:51 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.
Starting point is 00:03:04 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.
Starting point is 00:03:36 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.
Starting point is 00:03:59 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,
Starting point is 00:04:20 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.
Starting point is 00:04:39 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,
Starting point is 00:05:25 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
Starting point is 00:05:57 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
Starting point is 00:06:31 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.
Starting point is 00:06:48 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.
Starting point is 00:07:10 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
Starting point is 00:07:47 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.
Starting point is 00:07:59 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,
Starting point is 00:08:19 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,
Starting point is 00:08:32 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,
Starting point is 00:08:44 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.
Starting point is 00:09:26 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
Starting point is 00:09:54 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.
Starting point is 00:10:16 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
Starting point is 00:10:50 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.
Starting point is 00:11:08 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
Starting point is 00:11:41 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.
Starting point is 00:12:26 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.
Starting point is 00:12:55 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
Starting point is 00:13:39 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
Starting point is 00:14:26 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
Starting point is 00:15:13 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.
Starting point is 00:15:41 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.
Starting point is 00:15:58 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.
Starting point is 00:16:51 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
Starting point is 00:17:24 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
Starting point is 00:17:54 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
Starting point is 00:18:43 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.
Starting point is 00:19:04 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
Starting point is 00:19:20 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,
Starting point is 00:20:01 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.
Starting point is 00:20:47 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,
Starting point is 00:21:09 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
Starting point is 00:21:39 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
Starting point is 00:22:25 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.
Starting point is 00:22:59 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
Starting point is 00:23:37 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.
Starting point is 00:24:14 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.
Starting point is 00:24:46 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.
Starting point is 00:25:20 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.
Starting point is 00:26:10 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?
Starting point is 00:26:46 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,
Starting point is 00:27:00 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
Starting point is 00:27:42 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.
Starting point is 00:28:06 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
Starting point is 00:28:21 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
Starting point is 00:28:40 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,
Starting point is 00:28:56 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,
Starting point is 00:29:13 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?
Starting point is 00:29:43 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.
Starting point is 00:30:33 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
Starting point is 00:31:06 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?
Starting point is 00:31:45 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
Starting point is 00:32:32 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.
Starting point is 00:33:16 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.
Starting point is 00:33:46 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.
Starting point is 00:34:05 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
Starting point is 00:34:35 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
Starting point is 00:35:14 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.
Starting point is 00:35:46 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,
Starting point is 00:36:25 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.
Starting point is 00:36:59 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
Starting point is 00:37:40 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
Starting point is 00:38:34 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.
Starting point is 00:39:21 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.
Starting point is 00:39:58 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.
Starting point is 00:40:29 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
Starting point is 00:41:00 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.
Starting point is 00:41:28 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
Starting point is 00:41:51 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.
Starting point is 00:42:37 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.
Starting point is 00:43:18 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
Starting point is 00:43:53 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
Starting point is 00:44:19 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
Starting point is 00:45:10 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.
Starting point is 00:45:54 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.
Starting point is 00:46:38 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
Starting point is 00:47:17 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.
Starting point is 00:47:38 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.
Starting point is 00:47:53 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
Starting point is 00:48:09 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?
Starting point is 00:48:25 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.
Starting point is 00:49:09 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
Starting point is 00:49:33 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.
Starting point is 00:50:00 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.
Starting point is 00:50:28 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.
Starting point is 00:50:49 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
Starting point is 00:51:21 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
Starting point is 00:51:32 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.

There aren't comments yet for this episode. Click on any sentence in the transcript to leave a comment.