Earlier this year I tagged along with one of our sales guys to ask potential clients what was keeping each of them up at night. I heard two recurring themes:
- We investing heavily in Silverlight (or some other legacy tech stack). How do we modernize (usually to a web stack)?
- We have an insanely complex domain (usually sitting behind a set of interdependent web services), with a goal of modularity and maintainability. How do we turn this spaghetti into ravioli?
If you fall into camp #1 – check out this Silverlight Migration Strategies white paper here. Otherwise, keep reading…
Business/domain complexity is at the root of every enterprise software project. Mind exploding business and validation rules often result in code with seemingly infinite cyclomatic complexity scores, dependency graphs that make the most stoic architect weep, and code smells so strong you have to work remotely three days per week. What’s that, stakeholder? You need to create invoices using ten different calculation algorithms (with varying input), including various fluctuating currencies, distributed over three transports in one of four formats? And oh, next sprint will have two more calculation algorithms, each with a slightly different output? These types of rules are hard to document, much less turn into legible, maintainable, and testable code. There is no silver bullet for complexity, but following some best practices can help prevent a complex code base from turning into a big ball of mud.
The SOLID principles are a set of five guidelines that help make complex applications more maintainable and extendable over time. These principles are:
- SRP – The Single Responsibility Principle states that a class should have a single responsibility, with responsibility being defined as a reason to change. This is one of the most important of the five rules, and probably the most misunderstood and applied.
- OCP – The Open Close Principle states that modules and classes should be open for extension, but closed for modification.
- LSP – The Liskov Substitution Principle states that if subType derives from baseType, then substituting baseType with subType should not result in changes to the expectation in behavior of baseType. more simply, subtypes should have a strong “IS-A” relationship with their base classes.
- ISP – Interface Segregation Principle states that interfaces should be small and cohesive.
- DIP – The Dependency Inversion Principle states that a higher level module should not depend on a lower level module, but that both should depend on abstraction. Dependency Injection containers like Ninject, Unity, and Autofac are an example of the application of DIP.
A few examples go a long way in understand the subtleties of these principles. If you have 35 minutes to spare, check out my SOLID Principles course on WintellectNOW. Use code NSTIEGLITZ-13 for a two week free trail. If you’re interested in digging deep into these principles, I strong recommend picking up a copy of Bob Martin’s book: Agile Principles, Patterns, and Practices in C#.