欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

工厂方法模式(Factory Method Pattern)

程序员文章站 2022-06-15 11:30:24
...

前言介绍

简单工厂定义

​ 又称之为静态工厂方法。在简单工厂中,可以根据传递的参数不同,返回不同类的实例。简单工厂定义了一个类,这个类专门用于创建其他类的实例,这些被创建的类都有一个共同的父类。

简单工厂类图

工厂方法模式(Factory Method Pattern)

简单工厂类(SimpleFactory),专门用于创建实例类的工厂,提供一个方法(factoryMethod()),该方法根据传递的参数不同返回不同类的具体实例。

概述

定义

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

涉及的策略

依赖倒置原则(Dependency Inversion Principle): 要依赖抽象,不要依赖具体类。

模式结构

  • 抽象产品(product): 所有的产品必须实现这个共同的接口,这样一来,使用这些产品的类可以引用这个接口,而不是具体类。
  • 抽象工厂(Creator):实现了所有操纵产品的方法,但不实现工厂方法。Creator所有的子类都必须要实现factoryMethod()方法。
  • 具体产品(ConcreteProduct): 实现了factoryMethod(),以实际制造出产品。
  • 具体工厂(ConcreteCreator):制造产品的实际工厂。它负责创建一个或者多个具体产品,只有ConcreteCreator类知道如何创建这些产品。

类图

工厂方法模式(Factory Method Pattern)

note: 抽象工厂和抽象产品可以是接口也可以是抽象类。

需要注意的东西

  • 工厂方法模式是简单工厂模式的延伸。在工厂方法模式中,核心工厂类不在负责产品的创建,而是将具体的创建工作交给子类去完成。也就是说这个核心工厂仅仅只是提供创建的接口,具体实现方法交给继承它的子类去完成。当我们的系统需要增加其他新的对象时,我们只需要添加一个具体的产品和它的创建工厂即可,不需要对原工厂进行任何修改。
  • 变与不变 :由以上可知,产品和工厂均是变化的。

适用场景

1. 一个类不知道它所需要的对象的类。
2. 一个类通过其子类来指定创建对象。
3. 将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定。

设计模式的实现

场景说明

​ 在一个披萨店中,要根据不同客户的口味,生产不同的披萨,如素食披萨、希腊披萨等披萨。同时根据地域的不同生产出不同口味的披萨,如纽约口味披萨,芝加哥口味披萨。如果利用简单工厂,我们需要两个不同的工厂,NYPizzaFactory、ChicagoPizzaFactory。在该地域中有很多的披萨店,他们并不想依照总店的制作流程来生成披萨,而是希望采用他们自己的制作流程。

代码实现

package factoryMethod;

/**
 * <p>ClassName      PizzaStore
 * <p>Description    抽象工厂
 * <p>Author         ChongLou
 * <p>Version
 * <p>Date           2017/7/29 23:39
 */
public abstract class PizzaStore {
    public Pizza orderPizza(String type){
        Pizza pizza;
        pizza = createPizza(type);

        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();

        return pizza;
    }

    abstract Pizza createPizza(String type);
}

package factoryMethod;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>ClassName      Pizza
 * <p>Description    抽象产品类
 * <p>Author         ChongLou
 * <p>Version
 * <p>Date           2017/7/29 23:23
 */
public abstract class Pizza {

    private String name;                //名称
    private String dough;               //面团
    private String sause;               //酱料

    private List<String> toppings = new ArrayList<String>();       //佐料

    /**
     * 准备
     */
    public void prepare() {
        System.out.println( "Preparing " + name );
        System.out.println( "Tossing dough" );
        System.out.println( "Adding sause" );
        System.out.println( "Adding toppings" );
        for (int i = 0; i < toppings.size(); i++) {
            System.out.println( "   " + toppings.get( i ) );
        }
    }

    /**
     * 烘烤
     */
    public void bake() {
        System.out.println( "Bake for 25 minutes at 350" );
    }

    /**
     * 切片
     */
    public void cut() {
        System.out.println( "Cutting the pizza into diagonal slices" );
    }

    /**
     * 包装
     */
    public void box() {
        System.out.println( "Place pizza in official PizzaStore box" );
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDough() {
        return dough;
    }

    public void setDough(String dough) {
        this.dough = dough;
    }

    public String getSause() {
        return sause;
    }

    public void setSause(String sause) {
        this.sause = sause;
    }

    public List<String> getToppings() {
        return toppings;
    }

    public void setToppings(String toppingStr) {
        this.toppings.add( toppingStr );
    }
}
package factoryMethod;

/**
 * <p>ClassName      NYPizzaStore
 * <p>Description    纽约披萨分店
 * <p>Author         ChongLou
 * <p>Version
 * <p>Date           2017/7/29 23:43
 */
public class NYPizzaStore extends PizzaStore {

    Pizza createPizza(String type) {
        Pizza pizza = null;
        if ("cheese".equals( type )) {
            pizza = new NYStyleCheesePizza();
        } else if ("veggie".equals( type )) {
            pizza = new NYStyleCheesePizza();
        } else if ("clam".equals( type )) {
            pizza = new NYStyleCheesePizza();
        } else if ("pepperoni".equals( type )) {
            pizza = new NYStyleCheesePizza();
        }

        return pizza;
    }
}
package factoryMethod;

/**
 * <p>ClassName      ChicagoPizzaStore
 * <p>Description    芝加哥披萨分店
 * <p>Author         ChongLou
 * <p>Version
 * <p>Date           2017/7/29 23:46
 */
public class ChicagoPizzaStore extends PizzaStore {


    Pizza createPizza(String type) {
        Pizza pizza = null;
        if ("cheese".equals( type )) {
            pizza = new ChicagoStyleCheesePizza();
        } else if ("clam".equals( type )) {
            pizza = new ChicagoStyleCheesePizza();
        } else if ("pepperoni".equals( type )) {
            pizza = new ChicagoStyleCheesePizza();
        } else if ("veggie".equals( type )) {
            pizza = new ChicagoStyleCheesePizza();
        }
        return pizza;
    }
}
package factoryMethod;

/**
 * <p>ClassName      ChicagoStyleCheesePizza
 * <p>Description    芝加哥披萨(具体产品类)
 * <p>Author         ChongLou
 * <p>Version
 * <p>Date           2017/7/29 23:36
 */
public class ChicagoStyleCheesePizza extends Pizza {
    public ChicagoStyleCheesePizza() {
        setName( "Chicago Style Deep Dish Cheese Pizza" );
        setDough( "Extra Thick Crust Dough" );
        setSause( "Plum Tomato Sauce" );
        setToppings( "Shredded Mozzarella Cheese" );
    }

    public void cut() {
        System.out.println( "Cutting the Pizza into square slices" );
    }

}
package factoryMethod;

import java.util.ArrayList;

/**
 * <p>ClassName      NYStyleCheesePizza
 * <p>Description    纽约口味的披萨(具体产品类)
 * <p>Author         ChongLou
 * <p>Version
 * <p>Date           2017/7/29 23:30
 */
public class NYStyleCheesePizza extends Pizza {
    public NYStyleCheesePizza() {

        setName( "Ny Style Sauce and Cheese Pizza" );
        setDough( "Thin Crust Dough" );
        setSause( "Marinara Sauce" );
        setToppings( "Crated Reggiano Cheese" );
    }
}
package factoryMethod;

/**
 * <p>ClassName      TestFactoryMethod
 * <p>Description    测试类
 * <p>Author         ChongLou
 * <p>Version
 * <p>Date           2017/7/29 23:48
 */
public class TestFactoryMethod {
    public static void main(String[] args) {
        System.out.println( "---------芝加哥的深盘披萨---------" );
        ChicagoPizzaStore chicagoPizzaStore = new ChicagoPizzaStore();       //建立具体工厂
        Pizza joelPizza = chicagoPizzaStore.orderPizza( "cheese" );             //制造具体产品
        System.out.println( joelPizza.getName() );

        System.out.println( "---------纽约风味的披萨---------" );
        NYPizzaStore nyPizzaStore = new NYPizzaStore();
        Pizza ethanPizza = nyPizzaStore.orderPizza( "cheese" );
        System.out.println( ethanPizza.getName() );
    }
}

运行结果

工厂方法模式(Factory Method Pattern)

总结

暂无,继续写下文