Design Patterns Notes - factory method pattern and abstract factory pattern

Design Patterns

Factory method and abstract factory pattern model

If scenarios

有一个披萨店要卖披萨,这需要一段程序。由于披萨有多个类型,可以实现为以下代码:
public class PizzaStore {
    public void orderPizza(String type) {
        Pizza pizza;
        if ("a".equals(type)) {
            pizza = new APizza();
        } else if ("b".equals(type)) {
            pizza = new BPizza();
        } else {
            pizza = null;
        }

        if (pizza != null) {
            pizza.cut();
            pizza.box();
            pizza.finish();
        }

    }
}

The above program looks seemingly no problem. However, after the program finished first consider whether the needs of this part will change!

假设:店家想增加2种新口味的披萨,删除1种卖的不好的披萨。

In this case, it is necessary to modify the above code. However, in violation of the principles of design - 对扩展开放,对修改关闭. You know, usually demand will change, and repeatedly modify the code often makes the code difficult to maintain!

Consider 策略设计模式one of design principles - 封装需要变化的部分. Create a "class factory" to deal with 创建对象the demand, as follows:

public class PizzaFactory {
    /*
    并非静态方法
    */
    public Pizza createPizza(String type) {
        Pizza pizza;
        if ("a".equals(type)) {
            pizza = new APizza();
        } else if ("b".equals(type)) {
            pizza = new BPizza();
        } else {
            pizza = null;
        }
        return pizza;
    }
}

Accordingly, modified PizzaStore.java code, as follows:

public class PizzaStore {
    private PizzaFactory factory;

    public PizzaStore(PizzaFactory factory) {
        this.factory = factory;
    }

    public void orderPizza(String type) {
        //采用PizzaFactory来创建对象
        Pizza pizza = factory.createPizza(type);
        if (pizza != null) {
            pizza.cut();
            pizza.box();
            pizza.finish();
        }

    }
}

The code change package part, which is conducive to code reuse. Now the demand has changed, as follows:

假设:披萨店火了,国内很多地区都想要加盟,但是不同省份需要制作不同口味的披萨来满足当地人的需求。

At this time, allowing each franchise corresponds to a specific factory to create pizza. as follows:

public abstract class PizzaFactory {
    public abstract Pizza createPizza(String type);
}

public class APizzaFactory extends PizzaFactory{
    @Override
    public Pizza createPizza(String type) {
        Pizza pizza;
        if ("c".equals(type)) {
            pizza = new APizza();
        } else if ("d".equals(type)) {
            pizza = new BPizza();
        } else {
            pizza = null;
        }
        return pizza;
    }
}

The above process, a business area can directly use their own APizzaFactoryget a pizza object, and then 商家自己you can decide whether to box, cut, ie, 商家自己may not be required PizzaStore. Therefore, we can not control the entire process of making pizza. In order to strengthen quality control, it can be PizzaStoreabstracted, made an abstract class, and then make pizza 工厂方法join in, so all businesses realize the class.

public abstract class PizzaStore {

    public void orderPizza(String type) {
        //解耦
        Pizza pizza = createPizza(type);
        if (pizza != null) {
            pizza.cut();
            pizza.box();
            pizza.finish();
        }

    }
    //工厂方法
    protected abstract Pizza createPizza(String type);

}

public class APizzaStore extends PizzaStore {
    @Override
    public Pizza createPizza(String type) {
        Pizza pizza;
        if ("c".equals(type)) {
            pizza = new APizza();
        } else if ("d".equals(type)) {
            pizza = new BPizza();
        } else {
            pizza = null;
        }
        return pizza;
    }
}

It can be seen, 工厂方法but let subclasses decide on the specific objects you need to create in order to achieve the object package creation process.

Factory Method pattern

在类中定义一个创建对象的接口,让子类决定到底创建哪个具体的对象。从而把对象的实例化推出到了子类。

Dependency Inversion

依赖抽象,而不要依赖具体类。

This means that, do not let 高层组件dependence 低层组件, and both components should depend on the abstract.
The beginning of the code, PizzaStoredependent on all specific Pizza. Dependence subsequent code has decreased, because we make high-level components PizzaStorerely on a low-level components 具体的Pizzaabstract. This is the 工厂方法模式effect.

Inverted way of thinking

Thinking from top to bottom are: need a pizza shop class that can produce a variety of pizza, cut, packaged ...
upside down: the need for the production of pizza, they should have a common interface Pizza. Pizza made dependent on the abstract interface can, also depends particular pizza type interface, the interface creates particular pizza type can be defined as the return.

Guidelines

  • Do not hold variable 具体类references
    we want for the programming interface that relies abstract.
  • Do not let the class inherits specific class
    if the successor concrete, it will inevitably depend on the specific class.
  • Do not cover the base class method has been achieved
    if the child class overrides the method in the base class, say class is not suitable for BenQ inherited

Hypothesis

制作披萨需要各种原料,我们不希望各个加盟店自行决定,而是希望指定的原料工厂来提供。

A new method prepare, to prepare raw materials.

public abstract class Pizza {
    //某种原材料
    private Sault sault;

    public void finish() {

    }
    public void cut() {

    }
    public void box() {

    }

    public abstract void prepare();
}

public interface Sault {
}

Using different materials in different parts of the plant, the interface can be provided a raw material of plant:

public interface IngredientFactory {
    Sault createSault();
}

public class AIngredientFactory implements IngredientFactory {
    @Override
    public Sault createSault() {
        return new Sault(){
            @Override
            public String toString() {
                return "a sault";
            }
        };
    }
}

Specific pizza production:

public class APizza extends Pizza {
    private Sault sault;
    private IngredientFactory ingredientFactory = new AIngredientFactory();
    @Override
    public void prepare() {
        sault = ingredientFactory.createSault();
    }
}

Abstract factory pattern

提供接口来创建相关对象或依赖对象的家族,而不需要明确指明具体的类。

For example, the above ingredientFactory.createSault (), which does not specify a particular creation Sault. Our client code APizzaalso from specific Saultdecoupling.

Published 11 original articles · won praise 0 · Views 675

Guess you like

Origin blog.csdn.net/qq_38878217/article/details/104737673