I’m not a coder: the last time I wrote any functioning code was at Uni’ in the early 1990s.Â I can adapt other people’s scripts and, given enough time, write my own.Â I can knock up a bit of XHTML and CSS but writing real applications?Â Nope.Â Not my game.
Every now and again though, I come up against a development topic and I do find them interesting, if a little baffling.Â I guess that’s how devs feel when I talk infrastructure.
From 2004 to 2005, I worked for a company called Conchango (who are now part of EMC Consulting) – I had a great time there, but the company’s focus had shifted from infrastructure to web design agency and Java/.NET development (which, by the way, they were rather good at – with an impressive client list).Â Whilst I was there, it seemed that all I heard about was “agile” or “XP” (extreme programming… nothing to do withÂ Windows XP) and these were approaches that were taking the programming world by storm at the time.
Then, a few weeks ago, I had a similar experience at an Edge User Group meeting, where Ian Cooper (a C# MVP) was talking about the SOLID principles.Â Not being a coder, most of this went right over my head (I’m sure it would make perfect sense to my old mates from Uni’ who did follow a programming route, like Steve Knight), but it was interesting nonetheless – and, in common with some of the stuff I heard about in my days at Conchango, I’m sure the basic principles of what can go wrong with software projects could be applied to my infrastructure projects (with a little tweaking perhaps):
- Rigidity – difficult to change.
- Fragility – change one thing, breaks something else.
- Immobility – e.g. one part of the solution is welded into the application.
- Viscosity – wading through treacle, maintaining someone else’s software.
- Needless complexity – why did we do it that way?
- Needless repetition – Ctrl+C Ctrl+V is not an ideal programming paradigm!
- Opacity – it made sense to original developerâ€¦ but not now!
Because of these issues, maintenance quickly becomes an issue in software development and Robert C MartinÂ (@unclebobmartin – who had previously led the group that created Agile software development from Extreme programming techniques) codified the SOLID principles in hisÂ Agile Principles, Patterns and Practices in C# book (there is also a Hanselminutes podcast where Scott Hanselman and “Uncle Bob” Martin discuss the SOLID principlesÂ andÂ a follow-up where they discuss the relevance of SOLID).Â These principles are:
- Single responsibility principle
- Open/closed principle
- Liskov substitution principle
- Interface segregation principle
- Dependency inversion principle
This is the point where my brain starts to hurt, but please bear with me as I attempt to explain the rest of the contents of Ian’s presentation (or listen to the Hanselminutes podcast)!
The single responsibility principle
This principle states thatÂ a class should have only one reason to change.
Each responsibility is an axis of change and, when the requirements change, that change will be manifested through a change in responsibility among the classes. If a class assumes more than one responsibility, that class will have more than one reason to change, hence single responsibility.
Applying this principleÂ gives a developer a single concept to code for (also known as separation of concerns) so, for example, instead of having a GUI to display a purchase order, this may be separated into GUI, controller, and purchase order: the controller’s function is to get the data from the appropriate place, the GUI is only concerned with displaying that data, and the purchase order is not concerned with how it is displayed.
The open/closed principle
This principle states that software entities (classes, modules, functions, etc.) should be open for extension but closed for modification.
The thinking here is that, when a single change to a program results in a cascade of changes to dependent modules, the design becomes rigid but, if the open/closed principle is applied well, further changes are achieved by adding new code, not by changing old code that already works.
Some may think that it’s impossible to be both open to extension and closed to change: the key here is abstraction and composing.
For example, a financial model may have different rounding rules for different markets.Â This can be implemented with local rounding rules rather than changing the model each time the model is applied to a different market.
The Liskov substitution principle
This principle (attributed to Barbara Liskov) states that subtypes most be substitutable for their base types.Â Unfortunately, attempts to fix Liskov substitution problems often result in violations of the open/closed principle but, in essence, the validity of a model can be expressed only in terms of its clients so, for example, if there is a type called Bird (which has got wings and can fly), where what happens to penguin and emu when an attempt is made to implement the fly method? We need to be able to call fly for a penguin and handle it appropriately so there are effectively two solutions: change the type hierarchy; or refactor the type to express it differently – fly may become move, or we could have a flightless bird type and a running bird type.
The interface segregation principle
The interface segregation principle says that clients should not be forced to depend on methods they do not use.
Effectively, this means that clients should not be affected by changes that donâ€™t concern them (i.e. fat types couple disparate parts of the application).Â In essence,Â eachÂ interface should have smallest set of features that meet client requirementsÂ but this means itÂ may be necessary to create multiple interfaces within a class.
The dependency inversion principle
The dependency inversion principle states that high level models should not depend on low level models – both should depend on abstractions. In addition,Â abstractions should not depend on details. Details should depend upon abstractions.Â Â This is sometimes known as the Hollywood principle (“Don’t call us, we’ll call you”).Â So, where is the inversion?Â If a class structure is considered as a tree with the classes at the leaves and abstraction at the trunk, we depend on the tree, not the leaves, effectively inverting the tree and grasping by the roots (inversion of control).
Summing it up
I hope I’ve understood Ian’s presentation enough to do it justice here but to sum it up: the SOLID principles help to match computer science concepts such as cohesion and polymorphism to actual development in practice. Or, for dummies like me, if you write your code according to these principles, it can avoid problems later when the inevitable changes need to be made.
As an infrastructure guy, I don’t fully understand the details, but I can grasp the high level concepts and see that it’s not really so different to my world.Â Look at a desktop delivery architecture for a large enterprise:
- We abstract data from user objects, applications, operating system and hardware (which is possibly virtualised) and this gives us flexibility to extend (or substitute) parts of the infrastructure (well, that’s the idea anyway).
- We only include those components that we actually want to use (no games, or other consumer functionality).Â
- We construct servers with redundancy then build layers of software to construct service platformsÂ (which is a kind of dependency inversion).Â
OK, so the infrastructure links may seem tenuous, but the principle is sound.Â Sometimes it’s good for us infrastructure guys to take a look at how developers work…