java设计模式-学习笔记-创建型模式-工厂模式(二)

简单工厂遇到的问题

在《简单工厂模式》中利用了披萨实例介绍了简单工厂模式。在简单工厂模式中如果想开设多个披萨店。每个披萨店的制作方式和披萨种类都不一样。如果还是在Factory类中添加新的产品,就会操作Factory的复杂性。也不好定制不同披萨店的制作方式。这个时候如果还使用简单工厂模式,因为简单工厂模式是将披萨的制作流程完全承包了。

解决方案

可以这么解决。将制作披萨的方式交由各个披萨店执行,披萨的订单还是给披萨店自己处理。也就是说将Factory类中的createPizza声明为一个接口。子类负责createPizza实现,其他部分还是保持不变。

基本定义

工厂方法定义了一个创建对象的接口。由子类决定要怎么构建那些种类的产品。工厂方法模式让构建实例的方式下方到了子类当中

模式结构

Concrete:具体

ConcreteProduct 具体产品

Creator:创作者

ConcreteCreator:具体创作者

  1. Product :抽象产品。所有的产品必须实现这个共同的接口,这样一来 ,使用这些产品的类既可以引用这个接口。而不是具体。

  2. ConcreteProduct :具体产品。

  3. Creator :抽象工厂。它实现了所有操纵产品的方法,但不实现工厂方法Creator所有的子类都必须要实现factoryMethod()方法。

  4. ConcreteCreator:具体工厂。制造产品的实际工厂。它负责创建一个或者多个具体产品,只有ConcreteCreator类知道如何创建这些产品。(与简单工厂模式的区别在:我们的工厂模式是面向接口编程的,动态工厂模式)

模式实现

工厂模式是简单工厂模式的一种延伸。在工厂模式中工厂类不负责产品的构建。而是将创建工作交个子类完成。也就是说核心工厂类只提供一个接口,具体实现交个集成他的子类完成。当我们系统要增加其他新的对象时。我们只需要添加一些产品的种类,和它创建的工厂即可。不需要对原本工厂进行任何改变。很好的复合了“开闭原则”

类图

image-20201031111313787.png

代码

/**
 * 抽象工厂类,也是我们工厂设计模式的一个核心思想类(面向接口编程)
 */
public interface  Factory{
     Pizza createPizza(String typePizza);
}

/**
 * 抽象产品类,作为父类出现,提供给中pizza种类继承
 */
public abstract class Pizza {

    /**
     * prepare 准备 把…预备好;
     */
    public abstract void prepare();

    /**
     * make 制作
     */
    public abstract void make();

    /**
     * complete 完成
     */
    public abstract void  complete();


}

/**
 * 肉类披萨
 */
public class PizzaMeet extends Pizza {
    public void prepare() {
        System.out.println("准备肉类");
    }

    public void make() {
        System.out.println("开始制作肉类披萨");
    }

    public void complete() {
        System.out.println("肉类披萨制作成功");
    }
}

/**
 * 蔬菜披萨
 */
public class PizzaVegg  extends Pizza {
    public void prepare() {
        System.out.println("准备蔬菜");
    }

    public void make() {
        System.out.println("开始制作蔬菜披萨");
    }

    public void complete() {
        System.out.println("蔬菜披萨制作成功");
    }
}



/**
 * Store 商店
 */
public class PizzaStore1 implements Factory {

    /**
     * 现在来看,我们的这个店面,不管有多少pizza,都是由自己进行控制的,如果该店面增加了产品产品种类,只需要修改自己的
     * pizza店的代码就可以了,而不会影响其他店的正常运行
     *
     * @param typePizza
     * @return
     */
    @Override
    public Pizza createPizza(String typePizza) {
        if ("MEET".equals(typePizza)) {
            return new PizzaMeet();
        } else {
            return null;
        }
    }

    public void orderPizza(String typePizza) {
        System.out.println("客户开始预定pizza...披萨类型" + typePizza);
        Pizza pizza = createPizza(typePizza);
        pizza.prepare();
        pizza.make();
        pizza.complete();
        System.out.println("披萨制作完成");
    }

    public static void main(String[] args) {
        PizzaStore1 pizzaStore1 = new PizzaStore1();
        pizzaStore1.orderPizza("MEET");
    }
}
// 输出结果
客户开始预定pizza...披萨类型MEET
准备肉类
开始制作肉类披萨
肉类披萨制作成功
披萨制作完成

/**
 * 如果要新增pizza商店,我们只需要实现factory就可以了,不需要修改factory类
 * 如果我新增加分店的话,我不会影响其他店的正常开设,我只关心我目前所开店面的代码。
 * Store 商店
 */
public class PizzaStore2 implements  Factory{

    @Override
    public Pizza createPizza(String typePizza){
        if ("VGGE".equals(typePizza)) {
            return new PizzaVegg();
        } else {
            return null;
        }
    }

    public void orderPizza(String typePizza) {
        System.out.println("客户开始预定pizza...披萨类型" + typePizza);
        Pizza pizza = createPizza(typePizza);
        pizza.prepare();
        pizza.make();
        pizza.complete();
        System.out.println("披萨制作完成");
    }

    public static void main(String[] args) {
        PizzaStore2 pizzaStore2 = new PizzaStore2();
        pizzaStore2.orderPizza("VGGE");
    }
}

优缺点

优点

  1. 见工厂模式当中。用户只需要知道产品对应的工厂即可。不需要关注创建产品的细节。
  2. 每当需要添加新的产品种类时,只需要添加对应的产品和构建工厂即可,不需要对原本的工厂进行改变。符合“开闭原则”

缺点

  1. 每次添加产品是都需要添加对应的工厂。使系统中类的个数增加,在一定程度上增加了系统的复杂性

总结

1、工广方法模式完全符合“开闭原则”。

2、工厂方法模式使用继承或者实现,将对象的创建委托给子类,通过子类实现工厂方法来创建对象

3、工厂方法允许类将实例化延伸到子类进行。

4、在工厂方法模式中,创建者通常会包含依赖于抽象产品的代码,而这些抽象产品是、由子类创建的,创建者不需要真的知道在制作哪种具体产品。

你可能感兴趣的:(java设计模式-学习笔记-创建型模式-工厂模式(二))