I'm actually new to formal topic of architecture but knowledge you compressed here even with examples match with my decades of semi-proffesional experience. Good job!
I feel like I'm seeing almost the exact same presentation that John Ousterhout did himself, including the examples. Feels like it's almost word for word.
I agreed with basically this entire video except for the part around 31:00 where you defend OOP against unspecified TH-cam videos that critique it. I can only assume you include Brian Will's video "Object Oriented Programming is Bad", since it has millions of views and is the first search result for "OOP is bad". I have watched this video several times and always glean something new from it, it is packed with insight and wisdom. In my opinion, it makes a very strong argument against OOP -- and I think it integrates well with Ousterhout's philosophy! Will specifically criticizes fine-grained encapsulation, which I think is a big cause of "shallow classes". Procedural code is often simpler and easier to understand than the highly abstracted code produced by OOP -- against, something I think comports with Ousterhout.
Very nice video! I agree with you that using TDD to test and grow your module's interface is a great principle. I have applied this successfully when writing multiple modules. One great practical thing to mention here is to try to keep the unit-test code very close to the function's API declaration. Preferably so close that you can read the API description, look at the API itself and also see the "example code" for how it's supposed to be called and the expected outcomes/return codes. Testing frameworks like doctest for C++ and Python are great for achieving this.
Small tip for beginners, many small projects give you familiarity with platform but is not easy to get to big project but... You can try tailor your project to few diffeent "clients", wich must not by but offer some time to specify exceptations. This immediately expose maintainability problems and quickly learn you some best practices wich seemd overblown. From the DX side you can ask some friend developer to make some changes and spend time together to collect how process goes.
Great video, I'm a junior dev (just started my first internship). I'm planning on reading the book. Other than that, are there any good resources for developing this style of thinking and practical resources for designing such modules?
22:26 "All interfaces are a little leaky" You can have abstractions or you can have control. Exploiting the implementation to gain performance falls under control, give that up and it's no longer leaky.
100% disagree about "classitis". Keep 'em numerous and small... VERY small. Big interfaces, functions, and classes are what creates the complexity / cognitive load problem, not classitis. Classitis is the CURE there, not the cause. If you don't have a sense of architecture and modularity, then of course classitis is a problem. You don't want "spaghetti classes" for the same reason you don't want spaghetti code. However, if you don't have a reasoned architecture and modularity, then you've got a helluva bigger problem than classitis. And if you do have a reasoned architecture and modularity, then classitis vanishes as a "cognitive load" problem by simply wrapping the cohesive classes together under a single class or interface, i.e. the Facade Pattern. I also disagree about red-green-refactor encouraging poor design. Design should be considered when refactoring, so to say it's not encouraging design is to say the coder isn't considering design where he or she is supposed to be considering design. Such an oversight isn't a failure of the process, but rather of the coder. You could still maintain that the "one thing at a time" nature of Red-Green-Refactor encourages constant design overhaul. To a degree I'd agree... and I'd say that, to a degree, that's a good thing. Many of the suggestions in this video are encouraging more upfront design, and flirt with violating YAGNI, but the pitfalls and failures of upfront design are well established, and are the entire reason for Agile dev. A coherent architecture should be maintained throughout development, but that doesn't (and shouldn't!) require that it's a fixed architecture from start to finish. And again, as the many failures of the software industry in the past have proven and over, the nature of the required modifications to the initial planned architecture can only really be understood when constructing the software itself... and even moreso from the inevitability of future changing requirements. You don't want the overall design to be "no plan", but having a "comprehensive fixed plan" is just as bad, if not worse. You want a plan, an architecture, but also sufficient fluidity to deal with issues and potential improvements encountered during construction, not to mention sufficient fluidity to adapt to changing requirements. Finally, if the "one thing at a time" nature of Red-Green-Refactor is creating a problem of perpetual design overhaul, there's a relatively easy step to try to mitigate that. That's to have the developer complete and bear in mind many related test NAMES simultaneously. If you know in the coming hours and few day kinda/sorta what's going to need to be coded up, then the designing part of the refactoring step will be done with those considerations of coming needs in mind. (I feel that the test names are so important to TDD's process and value that the slogan should be "Name Red Green Refactor." It's the naming and the refactoring that are the hard part, the important part, the part that demands a real programmer and proper software development. For most tasks, any novice can do the red-green part, can slap together code that works.)
so your video examples are actually incorrect. the website header for example. having one header might seem the right thing to do but changing that means considering how it looks like in all pages when you make that change. instead if you have each page supplying its own headers, then the change can actually be isolated
I'm actually new to formal topic of architecture but knowledge you compressed here even with examples match with my decades of semi-proffesional experience.
Good job!
I feel like I'm seeing almost the exact same presentation that John Ousterhout did himself, including the examples. Feels like it's almost word for word.
I agreed with basically this entire video except for the part around 31:00 where you defend OOP against unspecified TH-cam videos that critique it. I can only assume you include Brian Will's video "Object Oriented Programming is Bad", since it has millions of views and is the first search result for "OOP is bad". I have watched this video several times and always glean something new from it, it is packed with insight and wisdom. In my opinion, it makes a very strong argument against OOP -- and I think it integrates well with Ousterhout's philosophy! Will specifically criticizes fine-grained encapsulation, which I think is a big cause of "shallow classes". Procedural code is often simpler and easier to understand than the highly abstracted code produced by OOP -- against, something I think comports with Ousterhout.
Spot on
🤡
Great video. Thanks for taking the time to make it. It deserves more views.
Very nice video! I agree with you that using TDD to test and grow your module's interface is a great principle. I have applied this successfully when writing multiple modules. One great practical thing to mention here is to try to keep the unit-test code very close to the function's API declaration. Preferably so close that you can read the API description, look at the API itself and also see the "example code" for how it's supposed to be called and the expected outcomes/return codes. Testing frameworks like doctest for C++ and Python are great for achieving this.
Small tip for beginners, many small projects give you familiarity with platform but is not easy to get to big project but...
You can try tailor your project to few diffeent "clients", wich must not by but offer some time to specify exceptations.
This immediately expose maintainability problems and quickly learn you some best practices wich seemd overblown.
From the DX side you can ask some friend developer to make some changes and spend time together to collect how process goes.
thanks for the insight. Make me want to read that book right away
Excellent breakdown, my friend!
this video is gold
Great video, I'm a junior dev (just started my first internship).
I'm planning on reading the book. Other than that, are there any good resources for developing this style of thinking and practical resources for designing such modules?
22:26 "All interfaces are a little leaky"
You can have abstractions or you can have control.
Exploiting the implementation to gain performance falls under control, give that up and it's no longer leaky.
29:17 I really agree with you
Simple is beauty
Very interesting, thanks
"have yet read" - I had not yet heard "yet" this way in the affirmative before today.
Goated video man
Awesome Howie
Sorry for the late THUMBS UP!
"...will get to why oop is actually good in another video..." 32:17 but never follows up on it 🤔
Could have just linked the original talk. Almost no own thoughts provided.
This talk seems familiar. I swear some University professor gave it on some video.
Yeah, yeah yeah, but people are pursuing recognition/promotion instead of what you are talking about.
100% disagree about "classitis". Keep 'em numerous and small... VERY small. Big interfaces, functions, and classes are what creates the complexity / cognitive load problem, not classitis. Classitis is the CURE there, not the cause.
If you don't have a sense of architecture and modularity, then of course classitis is a problem. You don't want "spaghetti classes" for the same reason you don't want spaghetti code. However, if you don't have a reasoned architecture and modularity, then you've got a helluva bigger problem than classitis. And if you do have a reasoned architecture and modularity, then classitis vanishes as a "cognitive load" problem by simply wrapping the cohesive classes together under a single class or interface, i.e. the Facade Pattern.
I also disagree about red-green-refactor encouraging poor design. Design should be considered when refactoring, so to say it's not encouraging design is to say the coder isn't considering design where he or she is supposed to be considering design. Such an oversight isn't a failure of the process, but rather of the coder.
You could still maintain that the "one thing at a time" nature of Red-Green-Refactor encourages constant design overhaul. To a degree I'd agree... and I'd say that, to a degree, that's a good thing. Many of the suggestions in this video are encouraging more upfront design, and flirt with violating YAGNI, but the pitfalls and failures of upfront design are well established, and are the entire reason for Agile dev. A coherent architecture should be maintained throughout development, but that doesn't (and shouldn't!) require that it's a fixed architecture from start to finish. And again, as the many failures of the software industry in the past have proven and over, the nature of the required modifications to the initial planned architecture can only really be understood when constructing the software itself... and even moreso from the inevitability of future changing requirements. You don't want the overall design to be "no plan", but having a "comprehensive fixed plan" is just as bad, if not worse. You want a plan, an architecture, but also sufficient fluidity to deal with issues and potential improvements encountered during construction, not to mention sufficient fluidity to adapt to changing requirements.
Finally, if the "one thing at a time" nature of Red-Green-Refactor is creating a problem of perpetual design overhaul, there's a relatively easy step to try to mitigate that. That's to have the developer complete and bear in mind many related test NAMES simultaneously. If you know in the coming hours and few day kinda/sorta what's going to need to be coded up, then the designing part of the refactoring step will be done with those considerations of coming needs in mind. (I feel that the test names are so important to TDD's process and value that the slogan should be "Name Red Green Refactor." It's the naming and the refactoring that are the hard part, the important part, the part that demands a real programmer and proper software development. For most tasks, any novice can do the red-green part, can slap together code that works.)
so your video examples are actually incorrect. the website header for example. having one header might seem the right thing to do but changing that means considering how it looks like in all pages when you make that change. instead if you have each page supplying its own headers, then the change can actually be isolated
so the counter intuitive thing here is that duplication is actually ok and you dont need to refactor things immediately
Where are the design concepts. This is just you talking about random coding situations