The SOLID Principles are a set of Object Oriented Design Principles that are very interrelated and when followed can improve your code. Additionally, they make a great acronym that implies the benefits of using the principles. In 2011, at NimblePros, we made a calendar of Software Craftsmanship Principles and made humorous images to go along with them. We continued making the calendar for three more years and then missed 2015. Now we’re making a software craftsmanship calendar for 2016. Please back the calendar on Kickstarter, so there will be a 2016 edition.
Single Responsibility Principle
While it might seem useful at the time to just keep this stuff together, you may eventually realize it isn’t.
Avoid tightly coupling your tools together.
Open Closed Principle
It’s important that your code be open to extension while being closed to modification. This means that you should be able to add additional functionality without significantly altering the existing functionality. Remember the dangers of changing code; bugs can easily be created.
Brain surgery is not necessary when putting on a hat.
Liskov Substitution Principle
Any class implementing an interface needs to be substitutable for that interface. For example, you can’t have missing functionality when implementing your interface, or it’s not really substitutable. Developers shouldn’t need to be careful about using a specific implementation of an interface. That was the point of using an interface.
If it looks like a duck, quacks like a duck, but needs batteries – you probably have the wrong abstraction.
Interface Segregation Principle
Your interface should match only the needs of its users. If you pile on too many features to your interface, you make it hard to implement and difficult to use. The implementations are also likely violating the Single Responsibility Principle just to implement your interface.
Tailor interfaces to individual client’s needs.
Dependency Inversion Principle
Don’t get too specific on your dependencies. Make sure that you’re depending on something stable. This is often some kind of an interface. In our example below, an outlet and a plug make the connection nicely. You don’t want to hard-code specifically to the connection you have; you might need to change your connection at some point.
Would you solder a lamp directly to the electrical wiring in a wall?
I hope you enjoyed these SOLID principle pictures. And if you want to see more of this kind of humorous take on important software development principles and ideas, back our Software Craftsmanship Calendar 2016 on Kickstarter.
Now that the dust has settled from the recent Software Engineering 101 event we put on in Cleveland, I figured I would repost some of the material I talked about. This means some of connections that I vocalized and supplement the material from the slides I used for Software Engineering 101.
Object Oriented Principles, Practices, and Patterns
My first talk of the day was on Object Oriented Principles, Practices, and Patterns in which I start by discussing some common principles of object oriented programming: abstraction, encapsulation, inheritance, polymorphism, and I added composition in for good measure, which of course isn’t on its own a principle, but I feel deserves to be mentioned as its own entity at that point.
I covered an assortment of good practices for software developers to follow. Since Steve Smith was following my talk with one on SOLID, so I didn’t take the opportunity to discuss the Open/Closed Principle, which states that your code should be open to extension and closed to modification. This means that you can add to the behavior of your code by adding new code and not modifying what you already have.
In my patterns section I covered two of my favorite design patterns: the Strategy Pattern and the Template Method Pattern. These two are great for discussing with people. They’re very similar yet very different; one encapsulates the structure of an algorithm and allows for modification of the details of the steps while the other focuses on allowing for different algorithms to be used interchangeably. Each uses polymorphism, abstraction, encapsulation, and inheritance. They’re simple to explain and demonstrate, and they’re also very powerful. This makes them great examples.
When we combine these principles and some design patterns we can achieve some great things. The strategy pattern is one of my favorite patterns, because it is very useful and improves maintainability greatly. I use it often. It uses, abstraction, encapsulation, composition, polymorphism, and either inheritance or interface implementation. On top of that it also helps follow the Open/Closed Principle, increasing the ease for changing the behavior of an application when the requirements change.
In my talk I was asked a great question, “if I don’t know design patterns, how will I know what I don’t know.” In other words, how can you possibly select the correct design problem to solve a problem. I recommended reading learning plenty just so you’ll be more prepared. There are plenty of books, and you don’t always need “the best” solution. Usually a good solution to the problem is enough. Steve Smith chimed in with a great answer though, he suggested practicing coding katas, which will often solve problems using design patterns or at least good, worthwhile practices.