Learn Java Design Patterns - Factory Pattern

An article to understand the factory pattern

Factory Pattern is one of the most commonly used design patterns in Java. This type of design pattern is a creational pattern, which provides an optimal way to create objects. In the factory pattern, we do not expose the creation logic to the client when creating the object, and we use a common interface to point to the newly created object. If the process of creating an object is complex and needs to be used in many places, then using the factory pattern can reduce a lot of repetitive code. And the creation and use of objects are separated, which plays a role of decoupling to a certain extent.

Classification of Factory Patterns

  • Simple Factory Pattern, also known as Static Factory Method Pattern.

  • Factory Method pattern, also known as Polymorphic Factory pattern or Virtual Constructor pattern;

  • Abstract Factory (Abstract Factory) mode, also known as Toolbox (Kit or Toolkit) mode.

Simple Factory Pattern

Strictly speaking, the simple factory pattern is not one of the 23 commonly used design patterns, it can only be regarded as a simple implementation of the factory pattern family. The Simple Factory pattern includes the following three roles:

  • Factory role: The core of the simple factory pattern, responsible for implementing all the internal logic of the object creation process.
  • Abstract Product Role: The common interface for all objects created by the Simple Factory pattern.
  • Concrete product roles: The creation goal of the simple factory pattern, all concrete product roles implement the abstract product role interface.

Simple Factory Pattern Example

factory role

package com.rul.designpattern.factory.simplefactory;

/**
 * factory role
 *
 * @author LuoRu
 */
public class AnimalFactory {

    public static Animal createAnimal(String animalType) {
        if (animalType == null) {
            return null;
        }
        if (animalType.equalsIgnoreCase("SHEEP")) {
            return new Sheep();
        } else if (animalType.equalsIgnoreCase("BIRD")) {
            return new Bird();
        } else if (animalType.equalsIgnoreCase("CAT")) {
            return new Cat();
        }
        return null;
    }
}

Abstract Product Persona

package com.rul.designpattern.factory.simplefactory;

/**
 * Abstract Product Persona
 *
 * @author LuoRu
 */
public interface Animal {
    void sound();
}

specific product roles

package com.rul.designpattern.factory.simplefactory;

/**
 * specific product roles
 *
 * @author LuoRu
 */
public class Bird implements Animal {

    public Bird() {
        System.out.println("new Bird");
    }

    @Override
    public void sound() {
        System.out.println("chirp~~~");
    }
}
package com.rul.designpattern.factory.simplefactory;

/**
 * specific product roles
 *
 * @author LuoRu
 */
public class Cat implements Animal {

    public Cat() {
        System.out.println("new Cat");
    }

    @Override
    public void sound() {
        System.out.println("mew~~~");
    }
}
package com.rul.designpattern.factory.simplefactory;

/**
 * specific product roles
 *
 * @author LuoRu
 */
public class Sheep implements Animal {

    public Sheep() {
        System.out.println("new Sheep");
    }

    @Override
    public void sound() {
        System.out.println("baa~~~");
    }
}

Factory Method Pattern

The Factory Method pattern is the most used pattern in the factory pattern family. In the factory method pattern, we are no longer responsible for the creation of all objects used by the same factory class. Instead, different factories are responsible for the creation of different objects, and different factories implement a common interface. The Factory Method pattern includes the following four roles:

  • Abstract Factory Role: The public interface of all factory classes that create objects.
  • Concrete factory roles: All concrete factory roles implement the abstract factory role interface, and each concrete factory role is responsible for the creation of an object.
  • Abstract Product Role: The public interface of all objects created by the Factory Method pattern.
  • Concrete product roles: The creation goal of the factory method pattern, all concrete product roles implement the abstract product role interface. A specific product is created by a dedicated specific factory.

Factory Method Pattern Example

abstract factory role

package com.rul.designpattern.factory.factorymethod;

/**
 * abstract factory role
 *
 * @author LuoRu
 */
public interface AnimalFactory {
    Animal create();
}

Specific factory roles

package com.rul.designpattern.factory.factorymethod;

/**
 * Specific factory roles
 *
 * @author LuoRu
 */
public class BirdFactory implements AnimalFactory {
    @Override
    public Animal create() {
        return new Bird();
    }
}

Abstract Product Persona

package com.rul.designpattern.factory.factorymethod;

/**
 * Abstract Product Persona
 *
 * @author LuoRu
 */
public interface Animal {
    void sound();
}

specific product roles

package com.rul.designpattern.factory.factorymethod;

/**
 * specific product roles
 *
 * @author LuoRu
 */
public class Bird implements Animal {

    public Bird() {
        System.out.println("new Bird");
    }

    @Override
    public void sound() {
        System.out.println("chirp~~~");
    }
}

Abstract Factory Pattern

In the factory method pattern, we all produce the same type of product, while the factory class in the abstract factory pattern can create not only one product, but a group of products. The abstract factory pattern includes the following four roles:

  • Abstract Factory Role: Common interface for all factory classes that create the same set of objects.
  • Concrete factory roles: All concrete factory roles implement the abstract factory role interface, and each concrete factory role is responsible for the creation of a set of objects.
  • Abstract product role: The public interface of objects of the same class (distinguished "same group") created by the abstract factory pattern.
  • Concrete product roles: the creation target of the abstract factory pattern, all concrete product roles implement an abstract product role interface. Products created in an abstract factory belong to the same product family.

Abstract Factory Pattern Example

abstract factory role

package com.rul.designpattern.factory.abstractfactory;

/**
 * abstract factory role
 * Ordnance Factory Interface
 *
 * @author LuoRu
 */
public interface WeaponsFactory {
    Gun createGun();

    Bullet createBullet();
}

Specific factory roles

package com.rul.designpattern.factory.abstractfactory;

/**
 * Specific factory roles
 * AK Factory class
 *
 * @author LuoRu
 */
public class AKFactory implements WeaponsFactory {
    @Override
    public Gun createGun() {
        return new AKGun();
    }

    @Override
    public Bullet createBullet() {
        return new AKBullet();
    }
}
package com.rul.designpattern.factory.abstractfactory;

/**
 * Specific factory roles
 * AK Factory class
 *
 * @author LuoRu
 */
public class M416Factory implements WeaponsFactory {
    @Override
    public Gun createGun() {
        return new M416Gun();
    }

    @Override
    public Bullet createBullet() {
        return new M416Bullet();
    }
}

Abstract Product Persona

package com.rul.designpattern.factory.abstractfactory;

/**
 * Abstract Product Persona
 * Firearm interface
 *
 * @author LuoRu
 */
public interface Gun {
    void shoot();
}
package com.rul.designpattern.factory.abstractfactory;

/**
 * Abstract Product Persona
 * bullet interface
 *
 * @author LuoRu
 */
public interface Bullet {
    void describe();
}

specific product roles

package com.rul.designpattern.factory.abstractfactory;

/**
 * specific product roles
 * AK Firearms
 *
 * @author LuoRu
 */
public class AKGun implements Gun {
    @Override
    public void shoot() {
        System.out.println("AK shoot...");
    }
}
package com.rul.designpattern.factory.abstractfactory;

/**
 * specific product roles
 * M416 Firearms
 *
 * @author LuoRu
 */
public class M416Gun implements Gun {
    @Override
    public void shoot() {
        System.out.println("M416 shoot...");
    }
}
package com.rul.designpattern.factory.abstractfactory;

/**
 * specific product roles
 * AK bullet
 *
 * @author LuoRu
 */
public class AKBullet implements Bullet {
    @Override
    public void describe() {
        System.out.println("AK Bullet");
    }
}
package com.rul.designpattern.factory.abstractfactory;

/**
 * specific product roles
 * M416 bullet
 *
 * @author LuoRu
 */
public class M416Bullet implements Bullet {
    @Override
    public void describe() {
        System.out.println("M416 Bullet");
    }
}

Tags: Design Pattern

Posted by Trs2988 on Wed, 01 Jun 2022 05:41:38 +0530