Pages

Tuesday, September 24, 2013

Keep calm and S.O.L.I.D

Last winter I had the chance to attend a talk by Robert.C.Martin(aka Uncle Bob) in Dublin. I think it was awesome. Uncle Bob is the author of Clean Code(I've got it signed by him in person :p) and also is a very influential person in the software industry.

I've been thinking to write something about some of the contributions he did to the industry and post it here on my blog since that talk.

One of the last things he said to us, was to read as much as we could...
Before starting to write this post I thought about those words for a while...
I think that it was a great advice.
Nobody negates that real experience is probably best, but reading books is also very important.
They carry the experiences of persons who were there before and also the rules and the principles those persons discovered and documented on their way.
Don't get me wrong, following rules and principles strictly does not always guarantee success("the world keeps changing") but understanding them can be of great help when facing great challenges.


So finally I decided to write this post about one of the biggest contributions of Uncle Bob to the world of object oriented programming, and that is the S.O.L.I.D principles.

Principle #1 
Single Responsibility Principle
If we have a class that has multiple responsibilities/features/reasons to change; Modifications done to it carry the risk of affecting other parts of the class(other responsibilities/features/reasons to change). 
In other words: Classes that do more than one thing are difficult to maintain. 


SRP says: "A class should have only one reason to change".
Lets have a look at an example:
 public class BMI {  
     //Stuff...  
      public void calculate(int heightInCm,int weightInGrms) {  
      //Implementation...  
     }  
     public void saveResults() {  
      //Implementation...  
     }   
     public TrainingPlan getTrainingPlan() {  
      //Implementation...  
     }  
 }  
As you can see, it is a clear example of a class with multiple reasons to change:

  •  Future business requirements might involve us changing the calculate method(e.g different metrics)
  •        Future business requirements might involve us changing the way the results are saved.
  •        Future business requirements might involve us changing the way the training plan is created based in the BMI.

We don't want all the above mentioned requirement changes to affect the class. If we don't seek for modularity at an early stage of development, we will very easily end up with difficult to maintain software.

What we need to do is think just on the one unique goal that the class will have.
Also we can think in what the class definitely will not do, so we can distiguish the other reasons to change that should not be there. Follow this way of thinking when fixing a violation of the SRP and it will help you detect the classes that you need to extract:

 public class BMICalculator {  
     //Stuff...  
         public void calculate(int heightInCm,int weightInGrms) {  
      //Implementation...  
     }  
     //Other methods that support the main goal of the class...  
 }  
 public class BMIToStorage {  
     //Stuff...  
         public void save(BMIResults results) {  
      //Implementation...  
     }  
     //Other methods that support the main goal of the class...  
 }  
 public class TrainingPlanCreator {  
     //Stuff...  
         public TrainingPlan getTrainingPlan(BMIResults results) {  
      //Implementation...  
     }  
     //Other methods that support the main goal of the class...  
 }  



Principle #2 
Open Close Principle

The motivation behind the Open Close principle is to extend/change behaviour without modifying the existing code. This principle says:
"modules should be open for extension but close for modification".
You probably think, that this sounds very contradictory, but in many OO programming languages like Java, there are mechanisms that will allow you to do this. 

One of those mechanisms is polymorphism. By defining abstract functions/methods

Let's have a look first at a violation of the open closed principle:

 public class Chef {  
      public void prepareMeal(Meal meal) {  
           if(meal.type.equals("veg")) {  
                prepareVeg();  
           }  
           else if(meal.type.equals("nonVeg")){  
                prepareNonVeg();  
           }  
      }  
      private void prepareVeg() {  
           //Implementation...  
      }  
      private void prepareNonVeg() {  
           //Implementation...  
      }  
 }  
 public class Meal {  
      String type;  
 }  
 public class NonVeg extends Meal {  
      public NonVeg() {  
           type = "nonVeg";  
      }  
 }  
 public class Veg extends Meal {  
      public Veg() {  
           type = "veg";  
      }  
 }  

In the above code, if a new requirement arrives saying to make some other type of meal different than veg and non veg, the class will need to be modified. The given above example is not maintainability friendly.

Let's see how to use polymorphism to remove that conditional logic and improve the solution:
 public class Chef {  
      public void prepareMeal(Meal meal) {  
           meal.cook();  
      }  
 }  
 public abstract class Meal {  
      public abstract void cook();  
 }  
 public class NonVeg extends Meal {  
      public void cook() {  
           //...  
      }  
 }  
 public class Veg extends Meal {  
      public void cook() {  
           //...  
      }  
 }  
As you can see the solution is more flexible, now it is easier to maintain and also we got rid of an evil flag that at long term will cause only problems when manipulating it. The class Meal that contains sensitive methods is open for extension but closed for modification.

The OCP principle is very powerful but we also must have in mind that by adding levels of abstraction(as alternative you can also think about Composition versus inheritance), we also increase the complexity and it is very important to understand that this principle should be applied only in those places where there is more likely to be often requirement changes. 

Principle #3 
Liskov substitution principle
This principle is concern about sub-classes classes replacing the behavior of their base class. 
If this occurs, the new classes can produce undesired effects when they are used/called in other parts of the program.

Liskov's Substitution Principle states that if a client is calling a base class, then the reference to the base class should be able to be replaced with a derived class without affecting the functionality of base class.

Lets have a look at an example of violation of this principle:

 public class Duck {  
      public void quack(){  
           //..            
      };  
      public void swim(){  
           //..  
    };  
 }  

Also a wild duck can quack and swim.
But what about Duck toys?

 public class DuckToy extends Duck {  
     private boolean batteriesIncluded;       
      public DuckToy(boolean batteriesIncluded) {  
           //...  
      }  
      public void swim() {  
           //...(This logic depends on the batteries)  
      }  
      public void playSound() {  
           //...  
      }  
 }  

As you see, some duck toys require batteries and also they don't really quack, they just play a sound. Even if there are no compilation errors and it looks tempting to include duck toy in this inheritance chain, this is clear violation of Liskov's substitution principle.
The reason is that if a client instantiates the base class, the derived class DuckToy, is not capable of replace it because the functionality is being affected.

 public class Pond {  
      public static void main(String[] args) {  
           Duck wildDuck = new WildDuck();  
           Duck duckToy = new DuckToy(true);  
           wildDuck.quack();  
           //This should not quack  
           duckToy.quack();  
           //Compilation error, real ducks don't play sounds or use batteries  
           //duckToy.playSound();  
      }  
 }  

One solution in this case could be to have a separate class by its own, to represent the duck toy.

 public class DuckToy {  
     private boolean batteriesIncluded;       
      public DuckToy(boolean batteriesIncluded) {  
           //...  
      }  
      public void swim() {  
           //...(This logic depends on the batteries)  
      }  
     public void quack() {  
           //Duck Toys don't quack  
      }  
      public void playSound() {  
           //...  
      }  
 }  

Principle #4 
Interface segregation principle

This is a very simple to understand principle, it says that clients should not be forced to implement interfaces they don't use Just that simple. Have a look at a violation of this principle:


 public interface Animal() {  
    public void fly();  
    public void run();  
    public void swim();  
 }  
 public class Dog implements Animal {  
    public void fly() {  
    //This is empty because dogs can't fly  
    }  
    public void run() {  
     //Implementation for running  
    }  
    public void swim() {  
     //Implementation for swimming  
    }  
 }  

That was horrible uh? So there are many ways you can avoid this.
One example could be to combine specific interfaces as per needed:

 public interface Runner() {  
    public void run();  
 }  
 public interface Swimmer() {  
    public void swim();  
 }  
 public interface Flyer() {  
    public void fly();  
 }  
 public class Dog implements Swimmer,Runner{  
    public void swim(){}  
    public void run(){}  
 }  
 public class Seagull implements Swimmer,Flyer{  
     public void swim(){}    
      public void fly(){}  
 }  

Degresion: While writing this example I just remembered a post that I wrote time ago about the use of Marker interfaces, that is also another interesting way of getting flexibility using interfaces. 

Principle #5 
Dependency inversion principle



This principle says "Don't depend on anything concrete, depend only on things that are abstract." So make sure that all of your dependencies point at things that are abstract.
This will bring safety to your code and also make it flexible.
Probably you are thinking that this principle, can be a bit radical; but obiously, in real following it always strictly is just very difficult(maybe even impossible).
A tip that you can use to verify that you are following this principle when you call a function, is to program to the interface and not the realization.

One great example of this principle in practice is the Template design pattern. Lets have a look first at a common violation of the principle:

 public class PizzaMaker {  
   public Pizza makeMeatPizza() {  
      Pizza pizza = new Pizza();  
     pizza.setBase(true);  
     pizza.setCheese(true);  
     pizza.setOregano(true);  
     pizza.setTomato(true);  
     pizza.setMeat(true);  
     cook(pizza);  
   }  
   public Pizza makeVeggiePizza() {  
      Pizza pizza = new Pizza();  
     pizza.setBase(true);  
     pizza.setCheese(true);  
     pizza.setOregano(true);  
     pizza.setTomato(true);  
     pizza.setMeat(false);  
     pizza.setVegetables(true);  
     cook(pizza);  
   }  
   private Pizza cook(Pizza pizza) {  
   //...  
   }  
 }  

The above example is a badly coded class that makes 2 types of pizzas... There are many bad things in this piece of code, but I will just focus on the violation of the principle we are discussing.
Since every call done to the pizza object is to a concrete method, what we get is something very rigid and inflexible.
Every pizza has some ingredients that are mandatory, such as the base, tomato, cheese and oregano,but the rest are optional, so: why do we care about making calls to concrete methods, to set those extra ingredients, if is not even our concern?

In the following snippet of code, a template method is introduced to abstract the optional part and let sub-classes implement them.

 public abstract class PizzaMaker {  
  //A method that has a call to an unimplemented abstract function,   
  //is known as a template method  
   public Pizza make() {  
     Pizza pizza = addBasicIngredients();  
     addSpecificIngredients(pizza);  
     cook(pizza);  
     return pizza;  
   }  
   public abstract void addSpecificIngredients(Pizza pizza);  
   private Pizza addBasicIngredients() {  
     Pizza pizza = new Pizza();  
     pizza.setBase(true);  
     pizza.setCheese(true);  
     pizza.setOregano(true);  
     pizza.setTomato(true);  
     return pizza;  
   }  
   private void cook(Pizza pizza) {  
     //...  
   }  
 }  
 public class MeatPizzaMaker extends PizzaMaker {  
   @Override  
   public void addSpecificIngredients(Pizza pizza) {  
     pizza.setMeat(true);  
     pizza.setVegetables(false);  
   }  
 }    
 public class VegetablesPizzaMaker extends PizzaMaker {  
   @Override  
   public void addSpecificIngredients(Pizza pizza) {  
     pizza.setMeat(false);  
     pizza.setVegetables(true);  
   }  
 }  

The S.O.L.I.D principles, were identified by Robert C.Martin, but the Acronym was created by Michael Feathers in the year 2000, today they are well known in the world of object oriented sofwtare and many there is plenty literature on books and internet about them.

Just for the end of this post I would like to share with you a great podcast interview that I found on the web, were Uncle Bob, explains S.O.L.I.D in detail.



Wednesday, September 4, 2013

In London you will never be hungry.

I recently arrived to London, I have to say that I am very impressed.
Everything is really beatiful and the weather is great. One of the things that kept my attention is the huge amount of places you can pick for eating. I love food, and while eating at an Indian place at whitechappel yesterday, I've got inspired for my next blog post.

Did your programming teacher ever gave you that exercise, where you had to create a program to pick some food from a restaurant menu and try to apply some design pattern to it?
While looking through the menu at that Indian place I was remembering that homework, and I think it was some kind of factory pattern what we were expected to use back then to solve it.

This article is about the "abstract factory" pattern. Because of its purpose, some people may also refer to it as the "Toolkit pattern".
Let's have a look at it...

The "abstract factory" pattern is an enhancement of the "factory method" pattern(maybe better to say-It uses it...). Let's just refresh quickly our minds about the "factory method" pattern.

The "factory method" pattern is a creational pattern that intents to release the client from the task of creating objects.
The main reasons are:
 -objects may have a complex/dependant initialization mechanism which does not interest the client.
 -the client doesn't know which is the object type that he needs until runtime.

To implement a factory method what we need is create a method that will take an argument(passed at runtime) and add to it conditional logic that will create one object type or other based on the passed parameter.

The only way in which abstract factory differs from factory method is that with abstract factory we just create factories and let the client use the factories for create objects.

Both "abstract factory" and "factory method" are widely used in software engineering. Now let's have look a simple example where an "abstract factory".

In this UML diagram, we see how the client interacts only with the abstract factory and even the objects that creates using those factories are abstract(Food). The client does not know or care at all how those objects are created. As a result, the client call is simplier and does not have complex conditional logic to decide the object that is required.


 public class Customer {  
   public void orderFood() {  
     System.out.println("Which type of food would you like?");  
     Scanner scanner = new Scanner(System.in);  
     System.out.println("1- Mexican");  
     System.out.println("2- Chinese");  
     System.out.println("3- Indian");  
     int option = scanner.nextInt();  
     FoodFactory factory = FactoryMaker.getFactory(option);  
     Food food = factory.prepareFood();  
     System.out.print("Here are your " + food.getClass().getName());  
   }  
 }  
In the above code we see what we just mentioned above. The client using the abstract factory only interacts with abstractions, so there is not much client code.
 public interface FoodFactory {  
   public Food prepareFood();  
 }  
If we want to extend our software and have some other types of factories, we need to implement the comon interface that the client uses to access the factories.
 public class MexicanFoodFactory implements FoodFactory {  
   @Override  
   public MexicanFood prepareFood() {  
     Scanner scanner = new Scanner(System.in);  
     System.out.println("Mexican food menu:");  
     System.out.println("1- Fajitas");  
     System.out.println("2- Tacos");  
     return getFood(scanner.nextInt());  
   }  
   private MexicanFood getFood(int choice) {  
     switch (choice) {  
       case 1:  
         return new Fajitas();  
       case 2:  
         return new Tacos();  
     }  
     return null;  
   }  
 }  
This code above is just one sample implementation of one of those factories. As you can see, it has a "factory method" pattern in itself that will help return the appropiate food object(Just notice that the return type is an abstract class)
 public class FactoryMaker {  
   public static FoodFactory getFactory(int choice) {  
     switch (choice) {  
       case 1:  
         return new MexicanFoodFactory();  
       case 2:  
         return new ChineseFoodFactory();  
       case 3:  
         return new IndianFoodFactory();  
     }  
     return null;  
   }  
 }  
But to allow the client create the factories we will need some kind of gadget that will allow the client create one factory or other at runtime. That is why we need this class called FactoryMaker(This is again another sample of "factory method" but it will return an abstract/interface type)
 public abstract class Food {  
 }  
 public abstract class MexicanFood extends Food {  
 }  
 public class Fajitas extends MexicanFood {  
 }  
This 3 classes above are just part of the domain model.If you want you can make abstract those that you don't need to instantiate using the "new" keyword. The factories task is to create each of the concrete objects but use abstract return types so the client does not know about the type of the object being returned.

 Even if this pattern looks really interesting there are 2 important disadvantages of using it:
 - the bigger the model gets(more products), the more difficult is to maintain.
 - it violates the open-closed principle


Bon Appetit!

Share with your friends