As mentioned in the original post, I’m realizing that the SOLID principles are not as…solid as it would seem. The first post outlined the problems I see with the Single Responsibility Principle, and in the second, I recommended ignoring the Open/Closed Principle, since it is confusing and most reasonable interpretations give bad advice. Now, let’s talk about the Liskov Substitution Principle, which, as it turns out, is not design advice at all.
As mentioned in the original post, I’m realizing that the SOLID principles are not as…solid as it would seem. The first post outlined the problems I see with the Single Responsibility Principle, but now I’d like to talk about the most confusing of the five, the Open/Closed Principle.
This principle states that software should be “open for extension, but closed for modification”. I find this summary extremely confusing and when I dug deeper I found a whole lot of bad advice. You should ignore this principle entirely. Let’s see why.
Been thinking about the SOLID principles recently, and I’m questioning their usefulness. They are vague, over-reaching, confusing and, in some cases, totally wrong. But they come from the right place. The problem is that they attempt to reduce nuanced concepts into pithy statements and lose a ton of the value in translation. This sends programmers down the wrong path (it certainly did for me).
As a review, the SOLID principles are:
- Single Responsibility Principle
- Open/Closed Principle
- Liskov Substitution Principle
- Interface Segregation Principle
- Dependency Inversion Principle
In this article, I’m going to pick apart the Single Responsibility Principle, and in four subsequent posts tackle the other principles.
I’ve spent a few hours each day the past week writing a basic HTTP service in Go. The service has a single endpoint that writes its request payload to a database table. I have spent more time setting up the development environment and toolchain than I have writing code. Having to design, build, and test a toolchain just to be able to write and deploy code is meta-work that I’m not excited about and, when we aggregate developer time, is a form of waste.
So I want to talk about what I think the most minimal things are needed for a reasonable development environment and how we can get that and keep it working.
Per my previous post, I’ve left Stitch Fix after six years to find something that fits my strengths and experience a bit better then the public going concern that Stitch Fix now is. This page will serve as a way to articulate what that might be, in particular what experiences I have that it might be worth sharing with you or your team.
This is about me and if you don’t care about that, there’s no sense reading this page. I just need a URL to point to :)
I’m no longer working for Stitch Fix (this was 100% my choice to be clear :). It’s been an amazing six years, so this post is a hopefully short one about why, and the next post will detail what I’m looking for at the moment.
In reference to my last post, someone pointed me to the Eventide Project, and my response was that I could not understand what the project was, what it did, or how it worked, despite volumes of documentation. Rather than detail out that project’s documentation failings, I thought it might be interesting to see a rubric that walks you through the information you need to give new and existing users the best information about an open source project.
I’ve been fascinated by event-sourced architectures and wanted to get some real experience with it, but I also didn’t want to set up massive infrastructure inside AWS, find 100 developers to test it out on, and potentially ruin a business by doing so.
So I created an application that I believe mimics the developer workflows and architectural decisions you have to make in order to add features to an event-sourced architecture and want to share what I found. Anyone who has done this in the large, would love to hear if this tracks with your experience.
My takeaways are that it encourages some good practices, creates handy de-coupling between components, but introduces some friction, as well as complication for building a UI.
Let’s see how.
Choosing technology has a huge impact on a team’s performance, and when you are starting out, you have a lot of decisions to make. We often get hung up on technical features, or weather we should use a framework or a bunch of libraries. The reality is you have to gain a deep understanding of the business realities coupled with your team’s values. From there, you then evaluate your startup cost (opportunity cost) against the cost to maintain the system over time (carrying cost) to arrive at the best decision. Technical features are a part, but a small one.
Martin Fowler recently tweeted a link to his blog post about Kent Beck’s four rules of simple design, which I think could be improved upon (and, which can lead programmers down the wrong path at times):
Kent’s rules, from Extreme Programming Explained are:
- Runs all the tests
- Has no duplicated logic. Be wary of hidden duplication like parallel class hierarchies
- States every intention important to the programmer
- Has the fewest possible classes and methods
In my experience, these don’t quite serve the needs of software design. My four rules might be that a well-designed system:
- is well-covered by passing tests.
- has no abstractions not directly needed by the program.
- has unambiguous behavior.
- requires the fewest number of concepts.
To me, these flow from what we do with software.