Book Review - A Philosophy of Software Design
This is a book I highly recommend. It's slightly below Beyond Legacy Code.
It's added a lot of words for concepts I've been using without good descriptors. The biggest of these is "cognitive load". I'm sure it's a well known concept; this book was the first place I found it.
While I was using google to see if I'd already written a review of the book, I found someone else's review; James Koppel.
It's a much better review of the details of the book than I'll write (I'm lazy). I disagree with his view of the book though. Which has me wondering if I missed something. I recommend reading his review. It's informative. He's critical of the book while liking it overall. His result is to recommend the book. I recommend it much stronger.
For me; PoSD is extremely aligned with my views and practices of software development. One thing I really enjoyed about James' review is his comment
This is a great example of a case of small-class-itis gone wrong.
I would wonder what he'd think of MicroObjects... but I'm pretty sure I know.
Is the difference between my view of the book and James' based on our development practices? No idea, but I'm sure we vary. Not many do it like I do.
One of my favorite points from the book is the concept that modules have a narrow interface and deep functionality.
The best modules are deep; they allow a lot of functionality to be accessed through a simple interface.
My perspective and interpretation of PoSD will be different than John's while he was writing. That's a given. The levels of difference is what I start to wonder about.
An example of this is the MVVM UI pattern. I ROYALLY misunderstood that based on my perception of what a good UI layer would be.
I developed an entire pattern around my misconception to represent what I thought a good UI looks like.
James says
the book’s central idea: deep modules ... A good module is deep: the interface should be much simpler than the implementation.
Beautiful, obvious, and impossible to disagree with. Unfortunately, it’s also objectively wrong.
To which... I disagree. I feel deep modules are AMAZING. I built a mobile app based on creating deep modules with narrow interfaces. The only one I have numbers for is one someone else was trying to 'shame' me with. The interface has 1 method. Underneath there are 70 classes. A lot of functionality hidden behind that single method call.
There's an amazing amount of functionality hidden from logging in. Network, json, tokens, credential store... All hidden. We just login.Login(username, password)
.
The narrow and deep is almost foundational to how I write code. Which puts the book's central idea exceptionally inline with my style of development.
This part of James' review loses me. I assume because I haven't read the the post that he's using as the basis.
The idea of a deep module is that it hides A LOT of complexity from you. Even if you have to know things, like error codes, the complexity it hides simplifies the work we have to do.
One part I disgree with the book is on classitis
... I wonder why... :)
I don't disagree with his reasoning though. The mass of interfaces will be incredibly destructive to the understandability of the whole - IFF you have to deal with them.
I end up with a lot of local interfaces. Maybe I shouldn't use them? I'm still experimenting. Most of the code doesn't care about most of the interfaces. If C# had a better way to hide them, I'd keep them hidden. This is one of the times I miss Java's package private
. It'd REALLY simplifiy the visibility that I'd like.
A PoSD view counter to a lot of the points James' brings up is
You're just talking about the specification, rather than how easy they are to use to write code that works.
I think both points have merit. James talks about having to understand a lot about the narrow interface and John talks about being able to use it.
I think these are orthogonal.
We can need to know a lot tp use something simple. The more flags we allow, the more we'll need to know to interact with the narrow interface.
We don't have to worry about the HOW of the flags, just understanding what they are.
This is why it's narrow and provides value. Implementation is hidden, complexity is hidden.
This is what I see PoSD advocating and something I agree with.
I think the value of this hidding is shown in his Decorator example with streams. The variation in working with streams, being able to decorate them, and still use the 'stream' functionality is great.
I really like the idea of "Define errors out of existence". Errors tend to be a state that can be represented. If not... then the app should probably crash.
This is ignoring the complexity arguments that I agree with.
I feel the arguments presented in the book follow the valuable practices I use when developing software. It's closely aligned with the concepts and practices I follow for MicroObjects.
I assume some bias for the book because I agree with it. It's my experience that's shown these things provide value when I'm creating software, I'm not gonna ignore that. :)
This is one of my highly recommended books for the ideas it presents.