Saturday, October 5, 2019

Decorator Design Pattern In Java

Greetings!

Decorator desgin pattern is a structural design pattern.
This is a pretty standards pattern in Java, especially in code related to input/output classes such as FileReader, BufferedReader.

Full source code for this blog post is at my github account. [source-code]

GoF definition.
"Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to sub classing for extending functionality."



This is very powerful pattern to add extra funtionality to an object through composition. Interestingly, we are doing it at runtime.
This gives us an alternative to subclassing.

"Subclassing adds behaviour at compile time, decorator adds behaviour at run time."

When we use inheritance to add additional functionality, we may end with long heirarchy with too many classes. With decorator design pattern, we only need to create base and additional functionality can be added by decorating that base.
This is sometimes called as wrapper. Term used by Josua Bloch in his famous book is Forwarder.

"Inheritance is one form of extension, but not necessarily the best way to achieve flexibility in our designs."

Steps

  • Create base interface.
  • Implement it to add core functionality.
  • Create abstract class by implementing the interface which also compose the same interface.
  • Extend abstract class to add extra functionality.

Working Example

Let's decorate what is above us. The Sky! Sky mainly has two forms. Noon and night. Depending on days condition Sky is decorated with clouds, stars.

We can start with our Sky.

package com.slmanju.patterns;

public interface Sky {

    void draw();

}


Night sky have dark behaviour.

package com.slmanju.patterns;

public class NightSky implements Sky {

    @Override
    public void draw() {
        System.out.println("Drawing sky with black color");
    }

}


Now we can have our AbstractSky which acts as the base decorator.

package com.slmanju.patterns;

public abstract class AbstractSky implements Sky {

    protected Sky sky;

    public AbstractSky(Sky sky) {
        this.sky = sky;
    }

}


Let's add some stars into the Sky.

package com.slmanju.patterns;

public class StarSky extends AbstractSky {

    public StarSky(Sky sky) {
        super(sky);
    }

    @Override
    public void draw() {
        sky.draw();
        System.out.println("Drawing stars");
    }

}


Now it is time to decorate our Sky.

package com.slmanju.patterns;

public class App  {

    public static void main(String[] args) {
        Sky night = new NightSky();
        night = new StarSky(night);
        night = new CloudySky(night);
        night.draw();

        System.out.println("---------");

        Sky sky = new RainySky(new CloudySky(new NoonSky()));
        sky.draw();
    }

}


Remember;
  • Classes should be open for extension but closed for modification.
  • You can extend your core functionality by decorating it.

Happy coding :)

Friday, October 4, 2019

Template Method Design Pattern In Java

Greetings!

Template Method pattern is a behavioral pattern.
We put our businesss logic in abstract in a super class and let the sub classes override specific steps without changing the original structure.

Source code for this post can be found in my github account. [source-code]

When we have a common steps to do something but some steps vary, we can do it using bunch of if else statements. But the problem is things are tightly coupled and when new things need to be added we have to change our class. This leads our class difficult to main. For these kind of problems Template Method can be used.

Definition of Gof;
"Defines the skeleton of an algorithm in a method, deferring some steps to sub-classes. Template Method lets sub-classes redefine certain steps of an algorithm without changing the algorithm's structure."


"Don't call us, we'll call you. - allow low-level components to hook themselves into a system, but the high-level components determine when they are need and how."

Template method has easy two steps.
  • Define algorithm steps in super class.
  • Implement specific steps in sub class.

Working Example

Let's say we want to generate document Pdf, Excell, etc. Each file can have different ways to generate the document but loading data from the database, convert document into stream, etc are commmon operations. But steps are same. We add those common steps into super class and let the sub class define the what varies.

We can start by creating super class. In our case it is DocumentTemplate. Note that template method is final.

package com.slmanju.patterns;

public abstract class DocumentTemplate {

    public final void getDocument() {
        System.out.println("Load information...");

        generate();

        System.out.println("Finalize document creation...");
    }

    protected abstract void generate();

}


Now we can extend it to create our concrete implementation.

package com.slmanju.patterns;

public class PdfDocumentTemplate extends DocumentTemplate {

    @Override
    protected void generate() {
        System.out.println("Generating pdf document.");
    }

}


Let's run our application.

package com.slmanju.patterns;

public class App {

    public static void main(String[] args) {
        DocumentTemplate documentTemplate = new PdfDocumentTemplate();
        documentTemplate.getDocument();

        System.out.println("----------");

        documentTemplate = new ExcelDocumentTemplate();
        documentTemplate.getDocument();
    }

}


Things to note;

  • Algorithm steps are fixed but some implementations may vary. Subclasses are responsible to override necessary steps.
  • Subclass doesn't call super class. Instead it is super class which controls the flow. This is called 'Hollywoord principle'.
  • What if a step is based on a condition? We can add if condition with a method which may implement by sub classes. This is called a Hook. Super class may provide the default condition.
  • Template method and Factory method patterns are look similar. But the intent is different. Factory method is for creating objects. Template method is to define behaviour.
  • Strategy pattern uses composition while Template method uses inheritance.

Happy coding :)

Strategy Design Pattern

Greetings!

Strategy pattern is a behavioral pattern. It is one of the easiest patterns to learn and one of the most used pattern.

Source code for this blog post can be found in my github account. [source-code]

Let's see the GoF definition;
"Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it."


"Algorithm" in this definition is not necessarily a mathematical algorithm. It is something that do a thing. Basically algorithm is just another name for a strategy.
This leads us to;

  • A class should be configured with an algorithm instead of implementing an algorithm directly.
  • An algorithm should be selected an exchanged at run time.

When we start OOP, we are fond of inheritance. But when it comes to separating the code into more manageable way, we choose composition over inheritance.
"Consider 'has-a' instead of 'is-a'"

We achieve this by extracting the volatile parts of our code and encapsulate them as objects.
"Separate the parts of the code that will change the most."

Working Example

Let's take a practical example. We need to have file storage service which can handle save, retrieve operations. There, we can have a class and simply put the saving logic into that class. May be, from the begining it is not clear. Let's say we choose to save files in local storage. But what if we want to save files in AWS? It is clear that we should manage it in separate class. We can start with local file storage and easily swith to AWS.

We start by creating our FileService

package com.slmanju.patterns;

public interface FileService {

    void save();

    void retrieve();

}


Let's create the LocalFileService

package com.slmanju.patterns;

public class LocalFileService implements FileService {

    @Override
    public void save() {
        System.out.println("Save file in local disk.");
    }

    @Override
    public void retrieve() {
        System.out.println("Retrieving file from local disk.");
    }

}


We are going to use this in our StorgeService

package com.slmanju.patterns;

public class StorageService {

    private FileService fileService;

    public StorageService(FileService fileService) {
        this.fileService = fileService;
    }

    public void setFileService(FileService fileService) {
        this.fileService = fileService;
    }
    
    public void save() {
        fileService.save();
    }

    public void retrieve() {
        fileService.retrieve();
    }

}


All set. Let's run our application.

package com.slmanju.patterns;

public class App {

    public static void main(String[] args) {
        FileService localFileService = new LocalFileService();

        StorageService storageService = new StorageService(localFileService);
        storageService.save();
        storageService.retrieve();

        System.out.println("------");

        FileService awsFileService = new AwsFileService();
        storageService.setFileService(awsFileService);
        storageService.save();
        storageService.retrieve();
    }

}



Remember;
  • Encapsulate what varies.
  • Favor composition over inheritance.
  • Program to interface, not implementation.

Happy coding!


Factory Method Design Pattern

Greetings!

Factory method design pattern is a creational design pattern which deals with creating objects.
Many misunderstand this pattern with simple factory helper class.

Source code for this post can be found in my github account. [source-code]

This is the definition given by GoF.
"Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory method lets a class defer instantiation to subclasses."

As in original GoF design pattern, we define an interface (abstract class) to create objects that lets the sub-class to decide how to create the object.


Let's see the actors in this design pattern.
  • Product - This is the final object we need to create. We are dealing only with abstraction here because we can have multiple types of products.
  • Factory - A class to create Product. But it doesn't directly create object. Instead it provides abstract method to create the Product. Sub classes of the Factory needs to implement that creation method.
  • ConcreteFactory - This class is responsible to create the actual Product.
  • Client - This class needs to use a Product. It uses correct Factory to construct the Product.

Working Example

To explain this, i'm going to create a hypothetical shooting game with trail and purchased versions. A player can select a weapon. How do you create TrailWeapon or PurchasedWeapon? Are you going to use multiple if else in everywhere? We do not need to do that. We can create separate factories for 2 versions.
This example needs multiple classes. Here i'll add only neccesary classes. You can get the full code from my github repository.

First, we create our Product interface which is Weapon.

package com.slmanju.patterns;

public interface Weapon {

    void fire();

    void load();

}


We can implement this to create a concrete product. Here it is Rifle.

package com.slmanju.patterns;

public class Rifle implements Weapon {

    @Override
    public void fire() {
        System.out.println("Firing with rifle.");
    }

    @Override
    public void load() {
        System.out.println("Loading bullets into rifle.");
    }

}


Then we can create our Factory, WeaponStore. Here createWeapon is our factory method.

package com.slmanju.patterns;

// factory
public abstract class WeaponStore {

    public final Weapon purchase(WeaponType weaponType) {
        Weapon weapon = createWeapon(weaponType);
        weapon.load();
        return weapon;
    }

    // factory method
    protected abstract Weapon createWeapon(WeaponType weaponType);

}


Anddd, this is jungle shooter game. Hence our concrete factory is JungleWeaponStore.

package com.slmanju.patterns;

public class JungleWeaponStore extends WeaponStore {

    @Override
    protected Weapon createWeapon(WeaponType weaponType) {
        switch (weaponType) {
            case RIFLE:
                return new Rifle();
            case SHOTGUN:
                return new Shotgun();
            default:
                return new NullWeapon();
        }
    }

}


All set. Now we can have a Warrior.

package com.slmanju.patterns;

public class Warrior {

    private Weapon weapon;

    public Warrior(Weapon weapon) {
        this.weapon = weapon;
    }

    public void fight() {
        weapon.fire();
    }

    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }

}


It is time to let our Warrior to go insdie jungle to defeat enemies.

package com.slmanju.patterns;

public class ShooterGame {

    public static void main(String[] args) {
        WeaponStore weaponStore = new JungleWeaponStore();
        Weapon weapon = weaponStore.purchase(WeaponType.RIFLE);
        Warrior warrior = new Warrior(weapon);
        warrior.fight();

        weapon = weaponStore.purchase(WeaponType.SHOTGUN);
        warrior.setWeapon(weapon);
        warrior.fight();
    }

}


I hope you get the idea of factory method design pattern.

Happy coding.


Sunday, September 29, 2019

Builder Design Pattern In Java

Greetings!

Builder design pattern is a creational design pattern which helps us creating objects.

According to GoF, Builder design pattern;
"Separate the construction of a complex object from its representation so that the same construction processes can create different representations."

Eventhough the original pattern description talked about complex object creation, most used scenario is to help constructing objects fluently.
Builder design pattern helps us to assemble objects part by parts hiding inner states.

In this post i'm going to talk only about normal object creation using this pattern.



As I said earlier, this is a convienient way to construct objects with many parameters. Let's say you have a class which needs 10 parameters. Are you going to create a constructor with 10 arguments? Which is very difficult to maintain and use. This is where i'm giong to use Builder design pattern.
Help to create objects with multiple parametes in simple way.
  • Create immutable objects.
  • Encapsulates code for construction and representation.

Disadvatanges

Just like any other design, this also has few disadvantages.

  • Requires to create a separate Builder class with same number of variables.
  • For separate objects, it will need to maintain separate builders as well.

Main Class

This is the real object we need to construct. We are not exposing a constructor for this. Even we do not give any setter method.

Builder

Holds the properties of the main class. Most of the time, we use this as an inner class. We provide setter methods for all the parameters (with fancy name) and return Builder it self for furthur processing. Once the client call the build method, it creates the object of the main class.

Working Example

Let's assume that we are going to create game and we need to initialize our player object. Player may have many properties which is too big for a constructor. (though i'm not going to use many for this demo.)


package com.slmanju.patterns;

public class Player {

    private final String alias;
    private final String weapon;
    private final String hair;

    private Player(Builder builder) {
        this.alias = builder.alias;
        this.weapon = builder.weapon;
        this.hair = builder.hair;
    }

    public String getAlias() {
        return alias;
    }

    public String getWeapon() {
        return weapon;
    }

    public String getHair() {
        return hair;
    }

    @Override
    public String toString() {
        return "Player{" +
                "alias='" + alias + '\'' +
                ", weapon='" + weapon + '\'' +
                ", hair='" + hair + '\'' +
                '}';
    }

    public static class Builder {

        private final String alias;
        private String weapon;
        private String hair;

        public Builder(String alias) {
            this.alias = alias;
        }

        public Builder withWeapon(String weapon) {
            this.weapon = weapon;
            return this;
        }

        public Builder withHair(String hair) {
            this.hair = hair;
            return this;
        }

        public Player build() {
            return new Player(this);
        }
    }

}


package com.slmanju.patterns;

public class App {

    public static void main(String[] args) {
        Player player = new Player.Builder("Nero").withWeapon("Sniper").withHair("curly").build();

        System.out.println(player);
    }

}


This is not the end of the Builder design pattern. Where, I didn't cover complex scenarios like inheritance which needs a separate blog post. Though, I hope this will help you in your daily development tasks.

Happy coding :)