Archive for the 'Technical Design' Category

Books, Technical Design, Uncategorized

Design Guidelines Part.1: Single Responsibility

Given a group of programmers and a defined problem you are guaranteed to get different opinions about the correct way to code the solution to the problem. This is natural and is to be encouraged. You can leverage the Wisdom of Crowd (a recommended read by the way!) and give your team the best chance of success if you hear out everyones ideas and evaluate the pros/cons of each offering - time-boxed of course since we need to eventually deliver something to the client. Of course, even in a meritocracy it comes down to a trade-off but when faced with such decisions I usually fall back on known and proven principles to guide me to what is "good design". So what are these principles?

As far as object model design goes, the widely-known principles that I prefer to follow are:

  1. The Single Responsibility Principle
  2. The Open-Closed Principle
  3. The Liskov Substitution Principle
  4. The Dependency Inversion Principle
  5. The Interface Segregation Principle
  6. The Principle of Least Astonishment

As far as overall architecture goes, some principles which I advocate following are:

  1. Don't Repeat Yourself (DRY)
  2. Keep It Simple Stupid (KISS)

Let's dive into some details...

The Single Responsibility Principle (SRP)

First, lets start with some definitions. Quoting from Wikipedia, the SRP states that:

"every object should have a single responsibility, and that all its services should be narrowly aligned with that responsibility."

An alternate, but less clear definition is: "a class should have one, and only one reason to change."

It is also referred to as the "Do One Thing" rule. What is important to understand here is that a "responsibility" is a purpose. People new to this concept often get the (incorrect) impression that it means single member function because they reason each member function does something different. SRP is about responsibilities, not methods.

But wait. Does this mean I can't have persistence logic in my Business objects? According to SRP that would be the case, but as always these are guidelines. It's not officially stated but I interpret the word responsibilities as realistically meaning "responsibilities that are likely to change". Although this requires some insight into how your objects will evolve over time.

Why do we need to consider SRP? Because:

  • It makes testing the class easier if it only has one responsibility;
  • Classes are easier to read since they have a narrower focus;
  • Classes are likely to have fewer LOC;
  • You'll get greater re-use of the component since the component wasn't bundled with several other responsibilities the upstream consumer doesn't want or need;
  • There is less tendency to resort to copy-and-paste programming (which is really, really bad) to reuse functionality because it was made atomic, and therefore highly reusable, in the first place;
  • You'll naturally tend toward greater cohesion (how strongly-related and focused the responsibilities of a single class are) - which is a good thing because it makes code more maintainable;
  • You'll avoid building in tight coupling across your classes (I'll explain this further in a moment...)

So what nasty things await if we disregard the SRP? Well if you have objects with multiple responsibilities then you are creating more than one reason for that object to change - which is bad because in classes with multiple responsibilities the responsibilities can't help but become coupled making it hard for the object to undergo changes to one responsibility without affecting the coupled responsibilities. It is far more preferable to have modular, single-responsibility classes that change independently of each other, and change less frequently because they are single-purpose. As well, ignoring SRP makes it more likely that you will develop object anti-patterns such as God Objects where individual objects know too much or do too much.

In summary, following the SRP makes life easier in the long run for the developers...Reading the code is easier. Maintaining the code is easier. Making changes to the code is easier. And re-using the code is easier.

As Martin Fowler says,"Programs should be structured in such a way that we can make changes easily. When we make a change we want to be able to jump to a single clear point in the system and make the change." He calls these divergent changes in a section called "Code Smells". Say no more!

SRP is a simple concept but invariably it is much harder to implement. You have to be vigilant and force yourself to take things out of your class moving them to separate classes. Sure there are going to be cases where you happily violate this principle but be aware of the ramifications when you make that trade-off.

Other Parts in the Series
Design Guidelines Part.2: Open-Closed Principle
Design Guidelines Part.3: The Liskov Substitution Principle

Technical Design

You still need the Proof Of Concept

When was the last time you did a Proof-of-Concept (POC) ? Not sure - well let me pose another question...When was the last time you embarked on a technical project/task that had a considerable degree of risk in it?

IMHO one of the primary responsibilities of the project stakeholder is to mitigate the risk associated with the technical components of the business. Let's think about that for a minute. What risks are there, and how do you mitigate them? Well apart from the obvious and well documented issues like high availability, application scalability, disaster recovery, data loss, security breaches, project overrun, etc one risk that impacts on the engineering team is the occasional, or often, reliance on 3rd parties for significant components of your technical offering.

Sure, your engineering team might by LAMP/.Net/RoR domain experts and are very comfortable working in an agile environment with AJAX-y interfaces and all the bells and whistles of modern "web 2.0" applications, but as time-to-market is important and in a world where open APIs and SaaS are becoming more prevalent, invariably you'll eventually want to integrate with other service providers.

Building in this dependency on an outside party inherently poses a risk that you want to assess before making a commitment to go that route. In some cases the risk is easily assessed by reviewing the subjective feedback and experience of others. In other cases the risk is harder to quantify. e.g does the operating system and firmware of smart phone W from telco X enable you to do feature Y using language Z ? A java/brew/symbian domain expert may know the capabilities of the language/platform but it's unlikely that they will be familiar with the latest offering from Nokia or Apple, and the restrictions (if any) placed on the phones by a given carrier.

Regardless of the domain expertise you think you have in-house, it's often prudent to commit to a POC to mitigate the risks introduced. When you think about it, the POC is really the first step in any project that involved dependency on unproven technical components. If it's not, then be aware that the risk you are exposed to is carried much later in the development cycle and therefore becomes more expensive, or impossible, or mitigate late in the cycle.