Get rid of Inheritance Forest: Part 1

Get rid of Inheritance Forest

While doing code review, I have seen many times that there is a potential danger of creating a lot of inherited classes, meaning a simple change in business requirements may make things unmanageable. So, surely, this is a serious code smell, and we must take action.

One of the business cases comes in my mind is.

Business Case
If criteria are interlinked, the outcome product can be any combination of those criteria.
To put it simply, say the requirement is:

 "We have to create a ball, and the ball can glow-in-the-dark, and/or it can be printed with a smiley, and/or it can be scented, etc."

So here, the two main criteria would be:

  1.  A ball can be decorated with (glow-in-the-dark properties, a smiley, scented, etc.)
   2. It can have any combination of the above properties like (a Disco-Light smiley ball, a smiley Sandalwood scented  ball, a glow-in-the-dark Rosy scented ball, etc.)

According to the requirements, If we try to solve the problem by create interfaces for each decoration:
IGlowinthedark
ISmiley
IScent
And then create a concrete product that implements either or all of the interfaces as per requirements and then implement the each interfaces method.

The design seems to be right in naked eye, as it maintains the "coding to an interface" principle and welcomes the future changes as well!

Fig 1: Multiple Inheritance

But, is it well designed?
Put your thinking cap on, before reading the next part of the article. 

In my opinion, most of the time this would not be considered a good design for this application. So, let me explain my reasoning...

The Problem
This design very poorly handles decorations. Why? Say we have n number of decorators (Glow-in-the-dark, Smiley, Scented, etc).  each has m number of implenetation So, there will be Cn(C(m)) possible combinations.

Each decorator has multiple implementation like 

IGlowinthedark can have Disco Lights, Led Light etc
ISmiley can have Happy meme,ROFL meme etc
IScent has different fragrances like Sandalwood,Rose etc.

When n and m is small, there is a relatively small number of combinations. But what if n and m is a large number? How many combinations are there then?

We'd need to create a concrete class for each possible combination, so if the total number of combinations of (n,m) are 1,000, then we have to create 1,000 concrete classes to satisfy all these different combinations, like a Disco-light smiley ball, a smiley Sandalwood scented  ball, a glow-in-the-dark Rosy scented ball, etc.  etc.)

This is a massive failure of our chosen design. Our code base will be large and unmanageable. Somehow, we need to deal with the combination problem—we need to change our design.

GOF to the Rescue
Can you guess which GOF patterns will rescue us? Take a look at the picture below for reference.

Can you find the pattern?

If you guessed Decorator then congratulations, you are correct! This pattern will rescue us from this scenario. There are many other Solution by which we can get rid of this problem in later tutorials I will discuss about other solutions.

But before we get to that, let's discuss why our previous design fails.

If we read the requirements minutely, we would understand that the complexity lies in creating the many different combinations of the decorators of the ball. Through inheritance, one concrete class describes only one possible combination, as its implements either or all (IGlowinthedark and ISmiley or IScent) so it is static in nature.

The combination is proportional to the number of concrete classes, so concrete classes linearly increase as the combination increases. Our main failure lies in failing to dynamically create combinations. As it is, the outcome creates an Inheritance Forest, which is ever-expanding as these combinations/individual implementation grow in number.

It is like printing 1,000 array elements manually without using any loop.

To solve this riddle we are searching for a way to create a dynamic combination to expel the Inheritance Forest. So, all problems boil down to the following question: How can we push combination/behavior runtime dynamically?

The Decorator Pattern
The intent of the Decorator pattern is to add responsibility/behavior at runtime to an Object. That's exactly the answer we're searching for.

How Decorator Works
In the Decorator pattern, we encapsulate the main/core object inside a wrapper interface. In this case, the main Object is Ball and the interface is IBall. Now, every responsibility/behavior/criteria also implements the same Interface IBall. In our case, Glow-in-the-dark, Smiley, Scent implement IBall as well. And we have a composition with the same interface (IBall), which acts as a Wrapper Object.

Through this technique, we can achieve two things:

1. Any component that implements IBall has a (HAS-A) relationship with another component that also implements IBall. Through this, we can associate any component with another and achieve dynamic behaviors.

2. One component performs its work, then delegates the work to its associated (HAS-A) component. Again, that component follows the same pattern, which creates a delegator chain. At last, it produces a concrete product made by any combination.



Let see the Diagram of Decorator
Fig 2: Decorator Pattern





.
Coding :

Enough theory now see How to achieve run time behaviors through decorator





Decorator Interface:

public interface IBall {
   
    public void createBall();

}


Core Component :
Now create the core component which is the base, on top of it will add behavior as wrapper Object.



package com.example.decorator;
public class CoreBall implements IBall{

    IBall wrappeBall;
    public CoreBall(IBall wrappeBall){
        this.wrappeBall=wrappeBall;
    }

    @Override
    public void createBall() {
    System.out.println("Ball creation End");
    if(wrappeBall !=null)
    wrappeBall.createBall();
    }

}


Wrapper Components:

Now we will create main wrapper Component like Colors of Ball (Red,Blue,Green) and materials of the ball (Rubber,Polythene,Plastic etc.) So we can create any combinations by using them.

Light.java
package com.example.decorator;

public class Light implements IBall {
    IBall wrappeBall;
    public Light(IBall wrappeBall) {
        this.wrappeBall = wrappeBall;
    }
    @Override
    public void createBall() {
        System.out.println("Decorate with Disco Light");
        if(wrappeBall !=null)
        wrappeBall.createBall();
    }
}
Smiley.java

package com.example.decorator;
public class Smiley implements IBall{
    IBall wrappeBall;

    public Smiley(IBall wrappeBall) {
        this.wrappeBall = wrappeBall;
    }

    @Override
    public void createBall() {
        System.out.println("Decorate with Happy Smiley");
        if(wrappeBall !=null)
        wrappeBall.createBall();
    }
}




Test:

No we will create Multiple combinations on the fly as each component implements IBall interface and expect a IBall interface as argument of constructor so we can pass any components into any other components.


Main.java

package com.example.decorator;

/**
* @author Shamik Mitra
*
*/
public class Main {
    public static void main(String args[]) {
        IBall ball = new Smiley(new Light(new Ball(null)));
        ball.createBall();
        System.out.println("*********");
       }
}

Output :

Decorate with Disco Light

Decorate with Smiley

Ball creation End

*********


TIP: we have learned that Decorator can create multiple combinations by delegating responsibilities so if there is a requirement where two or more constraints can combine with each other to make a new product we can think of Decorator and not going for Multiple Inheritance.




















Maven Custom Archetype and PlaceHolder

Maven Custom Archetype and PlaceHolder


In this article ,I will show you How to create your own Archetype in Maven so it can fit your company coding Structure template.

To do this  following steps need to be followed

  1. Create a maven Project using Eclipse which is used as your Custom archetype.
  2. I named it customArchitype.
  3. It’s pom.xml look like following
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.example</groupId>
 <artifactId>customArchitype</artifactId>
 <version>1.0.Example</version>
</project>

   
  1. Then create a folder structure META-INF/maven under src/main/resources.
  2. Now project structure look  like src/main/resources/META-INF/maven
  3. After that create a file called archetype.xml under aforesaid folder.

This file will look like following
archetype.xml
<archetype xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype/1.0.0 http://maven.apache.org/xsd/archetype-1.0.0.xsd">
 <id>customArchitype</id>
 <sources>
   <source>src/main/java/customArchitype/CustomExample.java</source>
 </sources>
 <testSources>
   <source>src/test/java/customArchitype/CustomExampleTest.java</source>
 </testSources>
</archetype>

This archetype.xml is the most important part, which tells about the project structure it creates. So here you can customize the Project Structure which is fit in your organization.

I will discuss each tag I used in this XML in a tabular format.



Tage name
Description
<id>customArchitype</id>
TThis is the tag which points your custom archetype project when you do archetype: generate it will find archetype project based on that. So it will be the artifact id of the pom.xml in my case customArchitype project. The artifact is customArchitype. Always use your custom archetype project’s artifact ID.
<source>src/main/java/customArchitype/CustomExample.java</source>
This tells about the src folder hierarchy which will be generated. To do that we have to create a folder call  archetype-resources under
src/main/resources and then create a java class called CustomExample.java maintaining the hierarchy written under the <source> tag
<testSources>
   <source>src/test/java/customArchitype/CustomExampleTest.java</source>
 </testSources>
This tells the test folder hierarchy which will be generated. To do that we have to create a folder call  archetype-resources under
src/main/resources and then create a java class called CustomExampleTest.java maintaining the hierarchy written under the <source> tag



CustomExample.java File

package ${groupId}.customArchitype;

public class CustomExample {
   
    public void printName(String name) {
        System.out.println("Hello" + name);
    }

}


CustomExampleTest.java File

package ${groupId}.customArchitype;

public class CustomExampleTest {
   
    public static void main(String[] args) {
        CustomExample example = new CustomExample();
        example.printName("Shamik");
    }

}


PlaceHolder :

Please note that  in package statement I wrote
package ${groupId}.customArchitype;


Because when we give group Id in archetype.generate command our sample project create that package and place the files under the same so I want to dynamically replace package value, Hence I wrote a placeholder ${groupId} which actually replace the value of group id which we will pass when invoking archetype: generate command.

7. Now The last step is to create a template of pom.xml which will be created when the project is created by archetype: generate command.

Also, that pom.xml will be placed under archetype-resources.




Template pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>${groupId}</groupId>
 <artifactId>${artifactId}</artifactId>
 <version>${version}</version>
 <packaging>jar</packaging>
 <name>Custom Archetype</name>
 <url>http://javaonfly.blogspot.in/</url>
 <dependencies>
   <dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <version>3.8.1</version>
     <scope>test</scope>
   </dependency>
 </dependencies>
</project>


Please note that in the groupId and artifactId tag I used the placeholder for the same reason stated above. But this is an important thing to do unless generated pom will not replace group id and artifact id given in archetype: generate command.

Overall Structure:

Maven custom Archetype directory structure



Test:

Now if you run following command

mvn archetype:generate   -DarchetypeGroupId=com.example -DarchetypeArtifactId=customArchitype  -DarchetypeVersion=1.0.Example  -DgroupId=com.example    -DartifactId=newArchitype  


It will create a new project called newArchitype

Generic version of this command

mvn archetype:generate   -DarchetypeGroupId=<custom-archetype group id>
-DarchetypeArtifactId=<custom-archetype artifactid>  -DarchetypeVersion=<custom-archetype version>-DgroupId=<new project Group Id>   -DartifactId=<new project artifact Id>     

This new project group id will replace all placeholders.






Factory Method VS Simple Factory

Factory Method VS Simple Factory

While taking Interview of a senior developer, Often I asked a question to the candidate that do you know Design pattern?

They Said yes and then I ask them what are some design patterns you familiar with and use in your project?

Most of the cases I got answer Factory pattern and Singleton Pattern!!!.


As this is an article on Factory I just ignore Singleton interview discussion here.

Next question from my side is, tell me a business case and write down code fragments for Factory method.

But unfortunately, they gave the example of Shape a well-known example in google, and end up with writing a Simple factory which is not considered as a Design pattern :).

In this article, I will not show How to write Simple factory or Factory method rather than I will discuss what are they exactly and when to use them.


In the course of taking  interviews, I realize some points,
  1. we are actually trying to memorize the Design pattern not able to understand what the problem context it tries to solve.
  2. Another realization is we are not analyzing the Business justification first and then apply pattern based on this rather we try to find where in the business requirements we can fit the pattern that I know.




Simple Factory:

When To Use: If your program only bothers about creating a family of Products so a client of your code can get any products of that family at runtime you should use the Simple factory.




Coding :

To achieve the same, we create an interface where we define the set of methods which are required for creating the desired Products, Those methods implementation can be varied in Actual implementations.


Now, We will Create a TopLevel class which usually has a Static method where the client passes the desired parameter to get the Actual implementation.

Please Note that Simple factory uses a Static method and returns the actual implementation based on the parameter pass by a client. Here Client may be another code which uses your API or a request from The Web etc.

Coding Template :

Say we want to create TV and our client want to get different kinds of TV from our program like LCD, LED, Black&White, COLOR,3D etc.

So we will create an Interface ITV which has a method createTV(),
Children of ITV interface actually provide the implementation of createTV() and client calls them through a static method by passing parameter(main method).



Interface

/**
*
*/
package com.example.factory;

/**
* @author Shamik Mitra
*
*/
public interface ITV {
   
    public void createTV();

}


SimpleFactory


/**
*
*/
package com.example.factory;

/**
* @author Shamik Mitra
*
*/
public class TVSimpleFactory {
   
    enum TVMODE{COLOR,LED,LCD,THREEDIM};
   
    public static ITV getTV(TVMODE mode){
       
        if(mode.equals(TVMODE.LED)){
            return new ITV(){

                @Override
                public void createTV() {
                    System.out.println("LED TV");
                   
                }
               
            };
        }
        return null;
    }
   
    public static void main(String[] args) {
        TVSimpleFactory.getTV(TVMODE.LED).createTV();
    }

}


Justification :

By Simple Factory, we abstract the creation of the product from our client. Only our client knows, by calling the Static method and passing the desired parameter it gets an Object of that TV type. But How TV is created client code does not know, Actually they are also least bother to know How you produce that product. I only care for my SONY LED not How they create the same.

So whenever you see there are chances to create many types of implementation of an Object use Simple factory there But hey don’t take this as a Silver bullet. Try to understand the business justification then apply the pattern on it may be it is provocative to use Simple factory for a Business requirements but it may happen you are thinking of a small scope but at a broader scope that will hurt your design , read the next to see how a simple change in business requirements can change the design.


Factory Method:


When To Use: If Business needs more than Object creation, to be precise If you want to control the creation process and control the use case where any parts of the use case can be customized we use the Factory method. To put it simple way, If you want to control an Algorithm/Strategy on a family of products. you can think factory method pattern and it plays very well with Template pattern where Template method control the Strategy/Algorithm and it steps are abstract which can be created in an actual implementation of Factory.

Use Factory method when you want to make a Framework where you want to take a control from creation of the Object to management of that Object, unlike Simple factory where you only bother about the creation of product not How to create and manage it.

Recall The Headfirst Pizza Example where orderPizza() method,  create Pizza then bake cut and Box it. So it is nothing but an Algorithm which stays same for all Pizza and orderPizza is a template Method.

But you can also add an abstract method called applyTax() method in orderPizza(), in the actual implementations of the factory you can apply tax decision on Region basis,  So I can tell I can have fine control over Pizza  Lifecycle,  Not only the creation also the management part.


Back to our Example. Now If Our Business requirements want we not only Create the TV also take orders and Ship the TV and based on the city shipping charge is applicable.

So, It is clear now we need to create an algorithm which will create Different Tv and shipped them and calculate Shipping charge so factory method is ideal here we can't do it by Simple Factory so change is needed in design


Coding : We create an Interface for Product. Actual implementation create concrete product along with this also we create an abstract class called factory where
We maintain the algorithm in a template method and abstract the product creation and necessary part of the strategy  so in the subclass of the factory we can implement them according to business requirement.



Coding Template :

Interface of Product

/**
*
*/
package com.example.factory;

/**
* @author Shamik Mitra
*
*/
public interface ITV {
   
    public void createTV();

}


AbstractFactory Class

/**
*
*/
package com.example.factory;

import com.example.factory.TVSimpleFactory.TVMODE;

/**
* @author Shamik Mitra
*
*/
public abstract class AbstractFactory {

    public final void orderTV() {
        createTV();
        int charge= shippingCharge();
        System.out.println("Shipping charge :: " + charge + " INR");

    }

    protected abstract int shippingCharge();

    protected abstract void createTV();

}



Concrete Factory

/**
*
*/
package com.example.factory;


/**
* @author Shamik Mitra
*
*/
public class LEDTVFactory extends AbstractFactory {
    @Override
    public int shippingCharge() {
        // TODO Auto-generated method stub
        return 1000;
    }

    @Override
    public void createTV() {

        new ITV() {
            @Override
            public void createTV() {
                System.out.println("LED TV");

            }

        }.createTV();

    }

    public static void main(String[] args) {
        AbstractFactory factory = new LEDTVFactory();
        factory.orderTV();
    }
}

Justification : By Factory method, we not only abstract the Product creation but take one step further here we also abstract the factory which creates the product. So the benefits are that we can control the creation of Product and management of the product. If you see the above code you can see We abstract the factory with the ITV interface and in the Abstract factory, we create a template method which controls the TV lifecycle -- create TV and Shipping cost calculation and make them abstract so Children of Abstract factory can change them accordingly.

We can say Factory method Abstract the Creator from the caller. One level more abstract than Simple factory.

Benefits:

Create a Framework.
Control Product lifecycle.


TIP: If you only deal with the family of products go for Simple Factory but If you need to control the product creation and management go for Factory method.