S.O.L.I.D. Software Development, One Step at a Time (Cont.)
S.O.L.I.D. Stepping Stones
When you start asking the question of how, it’s a little like looking at a marathon race and wondering how you end up at the finish line. Obviously, for a marathon you arrive at the finish line by running one step at a time. Software development lets you move one step at a time toward your object-oriented goals, as well. The steps are composed of additional principles and implementation goals, such as those outlined in the SOLID acronym:
- S: Single Responsibility Principle (SRP)
- O: Open-Closed Principle (OCP)
- L: Liskov Substitution Principle (LSP)
- I: Interface Segregation Principle (ISP)
- D: Dependency Inversion Principle (DIP)
Originally compiled by Robert C. Martin in the 1990s, these principles provide a clear pathway for moving from tightly coupled code with poor cohesion and little encapsulation to the desired results of loosely coupled code, operating very cohesively and encapsulating the real needs of the business appropriately.
The Single Responsibility Principle says that classes, modules, etc., should have one and only one reason to change. This helps to drive cohesion into a system and can be used as a measure of coupling as well.
The Open-Closed Principle indicates how a system can be extended by modifying the behavior of individual classes or modules, without having to modify the class or module itself. This helps you create well-encapsulated, highly cohesive systems.
The Liskov Substitution Principle also helps with encapsulation and cohesion. This principle says that you should not violate the intent or semantics of the abstraction that you are inheriting from or implementing.
The Interface Segregation Principle helps to make your system easy to understand and use. It says that you should not force a client to depend on an interface (API) that the client does not need. This helps you develop well-encapsulated, cohesive set of parts.
The Dependency Inversion Principle helps you to understand how to correctly bind your system together. It tells you to have your implementation detail depend on the higher-level policy abstractions, and not the other way around. This helps you to move toward a system that is coupled correctly, and directly influences that system’s encapsulation and cohesion.
Throughout the rest of this article, I will walk through a scenario of creating a software system. You will see how the five SOLID principles can help you to achieve strong encapsulation, high cohesion, and low coupling. You will see how you can start with a 50-meter “get it done now” dash, and end with a long term marathon of updates to the system’s functionality.
Setting the Pace: A 50-Meter Dash
To help understand how you can achieve the goal of an object-oriented system through the use of the SOLID principles, I’ll walk you through a simple scenario, a solution, and the resulting expectations.
Scenario: Email an Error Log
One day at the office, your manager walks into your cube and looks like his hair is on fire. He informs you that his manager, the CTO, just got off the phone with a very irate customer. Apparently, one of your company’s hosted applications is throwing exceptions and preventing the customer from being able to complete their work.
The CTO has informed your manager that he needs immediate knowledge of the exceptions being thrown from this system, and personally wants to see an email in his inbox for every exception thrown, until the system is fixed. Your manager, worried about keeping his job, now wants you to create a quick-and-dirty application that allows a network operations person to send the contents of a log file to the CTO. Furthermore, this thing has to be out the door and in the hands of the network operations person before lunch-a couple of hours from now. Using a running analogy, you are now engaged in a 50-meter dash. You need to crank this code out and deliver it as quickly as possible.
Solution: Select a File and Send It
A few hours after that conversation with your manager, you have produced a very simple system that allows the user to select a file and send the contents of that file via email (Figure 4).
Figure 4: Application structure to send file contents.
The implementation of this application is very crude by your own standards: you coded the entire application in the form’s code, did no official testing, and did the bare minimum of exception handling (Listing 1). However, you got the job done.
New Expectation: All Errors Emailed
A week after you wrote that quick-and-dirty email sending application, your boss is back in your cube to talk about it again. This time, he informs you that your application was a smashing success and the CTO has mandated that all systems send error log emails to a special email address for collecting them. The CTO wants you, specifically, to handle this since your original application was received so well.
Figure 5: A class with many reasons to change.
Resetting the Pace
As your first assignment, after hearing about this new mandate from the CTO, you want to figure out what log files the network operations personnel will need to send, and how they want to facilitate this. After some discussion with the operations group lead, you have agreed to add two new aspects of functionality of the system:
- The operations people want an API to code against for some of their automation scripts.
- They need to parse the contents of an XML file to make it a little more human-readable.
You have also negotiated a slightly better timeframe with the network operations people than your manager gave you for the original application. They have agreed to a delivery date of close-of-business, tomorrow.
With this new deadline and the new requirements in mind, you decide to settle in for a slightly longer race than the original 50-meter dash. The code you started with was sufficient at the time, but now you need to enhance and extend it. You could consider this a 100- or possibly a 400-meter race at this point. The good news is that you know how to set your pace according to the situation you find yourself in.