【设计模式】工厂方法模式Factory(Java)(设计与模式)

【设计模式】工厂方法模式Factory(Java)(设计与模式)-图1

文章目录
  • 1. 定义
  • 2. 类图
  • 3. Java实现案例
    • 3.1 抽象类:Pizza和PizzaStore
    • 3.2 具体披萨:北京两种上海两种共四种
    • 3.3 具体披萨店:北京店和上海店
    • 3.4 测试主方法

1. 定义

工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类的实例化推迟到子类

2. 类图

  • 所以具体产品必须实现一个共同的Product接口(抽象类)
  • Creator是一个抽象类,它实现了所有到操作产品的方法,但不实现工厂方法factoryMethod
  • ConcreteCreator负责创建一个或多个具体Product
  • 工厂方法主要用来处理对象的创建,并将创建对象的行为封装在子类中

这里遵循依赖倒置的原则:要依赖抽象,不要依赖具体类

注意⚠️:在设计模式中,“实现一个接口”不一定就是指“写一个类,并利用implement关键词来实现某个java接口”,“实现一个接口”泛指实现某个超类型(类或者接口)的某个方法

3. Java实现案例

场景:

  • 披萨店生产披萨
  • 披萨有相同的处理流程,但有不同的处理方法,比如披萨都需要烘烤,但不同的披萨也许有不同的烘烤温度要求
  • 不同的披萨店能制作的披萨类型也不同
  • 易于扩展,增加新类型的披萨或新的披萨店

思考准备:

  • 根据工厂方法的类图,Product即为披萨、Creator即为披萨店,因此设计抽象Class:披萨、披萨店
  • 根据“工厂方法主要用来处理对象的创建,并将创建对象的行为封装在子类中”,我们需要在抽象Creator中设计抽象创建披萨店方法,并由继承它的子类进行具体实现
  • 易于扩展,具体披萨类继承抽象披萨类、具体披萨店类继承抽象披萨店类。

3.1 抽象类:Pizza和PizzaStore

Pizza:

package Factory;

import java.util.ArrayList;


public abstract class Pizza {

    String name; // 名称
    String dough; // 面团类型
    String sauce; // 酱料类型
    ArrayList toppings = new ArrayList(); // 一套装饰品佐料

    // 准备
    void prepare(){
        System.out.println("Preparing " + name);

        System.out.println("Tossing dough..");

        System.out.println("Adding sauce..");

        System.out.println("Adding toppings:");
        for(int i = 0; i < toppings.size(); i++){
            System.out.println("  " + toppings.get(i));
        }
    }

    // 烘焙
    void bake(){
        System.out.println("Bake for 30 min at 360");
    }
    // 分切
    void cut(){
        System.out.println("Cutting the pizza into diagonal slices");
    }
    // 打包
    void box(){
        System.out.println("Place pizza in official PizzaStore box");
    }

    public String getName(){
        return name;
    }



}

PizzaStore:

package Factory;


public abstract class PizzaStore {
    public Pizza orderPizza(String type){
        Pizza pizza;
        // 创建披萨
        pizza = createPizza(type);
        // 制作披萨并打包
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        // 返回披萨
        return pizza;
    }

    protected abstract Pizza createPizza(String type);
}

3.2 具体披萨:北京两种上海两种共四种

北京披萨1

package Factory;


public class BjStyleCheesePizza extends Pizza {
    public BjStyleCheesePizza(){
        name = "BeiJing Cheese Pizza";
        dough = "Thin Curst Dough";
        sauce = "LaoGanMa Sauce";

        toppings.add("Grated Reggiano Cheese");
    }
}

北京披萨2

package Factory;


public class BjStyleVeggiePizza extends Pizza {


    public BjStyleVeggiePizza(){
        name = "BeiJing Veggie Pizza";
        dough = "Bj2 Dough";
        sauce = "Bj2 Sauce";

        toppings.add("Bj2 Cheese");
    }

    // 这个北京披萨覆盖了cut方法,将披萨切成正方形
    @Override
    void cut() {
        System.out.println("Cutting the pizza into square slices");
    }
}

上海披萨1

package Factory;


public class ShStyleCheesePizza extends Pizza {
    public ShStyleCheesePizza(){
        name = "Shanghai Veggie Pizza";
        dough = "Sh2 Dough";
        sauce = "Sh2 Sauce";

        toppings.add("Sh2 Cheese");
    }
}

上海披萨2

package Factory;


public class ShStyleVeggiePizza extends Pizza {
    public ShStyleVeggiePizza(){
        name = "Shanghai Veggie Pizza";
        dough = "Sh2 Dough";
        sauce = "Sh2 Sauce";

        toppings.add("Sh2 Cheese");
    }
}

3.3 具体披萨店:北京店和上海店

工厂方法主要用来处理对象的创建,并将创建对象的行为封装在子类中。在本Demo中“创建对象的行为”即具体类中的createPizza方法。

北京店能生产北京的两种披萨

package Factory;


public class BeiJingPizzaStore extends PizzaStore{
    @Override
    protected Pizza createPizza(String type) {
        if (type.equals("cheese")){
            return new BjStyleCheesePizza();
        } else if (type.equals("veggie")) {
            return new BjStyleVeggiePizza();
        }
        // 等等其他类型的上海披萨

        return null;
    }
}

同理,上海店能生产上海店两种披萨

package Factory;


public class ShangHaiPizzaStore extends PizzaStore{
    @Override
    protected Pizza createPizza(String type) {
        if (type.equals("cheese")){
            return new ShStyleCheesePizza();
        } else if (type.equals("veggie")) {
            return new ShStyleVeggiePizza();
        }
        // 等等其他类型的上海披萨

        return null;
    }
}

3.4 测试主方法
package Factory;


public class MainPizzaTest {
    public static void main(String[] args) {


        PizzaStore pizzaStore1 = new BeiJingPizzaStore(); // 北京披萨店
        Pizza cheeseFormBj = pizzaStore1.orderPizza("cheese"); // 点一份cheese
        System.out.println(cheeseFormBj.getName());


        // 其他同上,如预定上海披萨店的Veggie披萨

    }
}

输出:

代码结构:

参考文献:《Head First设计模式(中文版)》弗里曼

转载请说明出处 内容投诉内容投诉
南趣百科 » 【设计模式】工厂方法模式Factory(Java)(设计与模式)

南趣百科分享生活经验知识,是您实用的生活科普指南。

查看演示 官网购买