工厂方法模式(Factory Method Pattern)
程序员文章站
2022-06-15 11:30:24
...
前言介绍
简单工厂定义
又称之为静态工厂方法。在简单工厂中,可以根据传递的参数不同,返回不同类的实例。简单工厂定义了一个类,这个类专门用于创建其他类的实例,这些被创建的类都有一个共同的父类。
简单工厂类图
简单工厂类(SimpleFactory),专门用于创建实例类的工厂,提供一个方法(factoryMethod()),该方法根据传递的参数不同返回不同类的具体实例。
概述
定义
工厂方法模式(Factory Method Pattern)定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
涉及的策略
依赖倒置原则(Dependency Inversion Principle): 要依赖抽象,不要依赖具体类。
模式结构
- 抽象产品(product): 所有的产品必须实现这个共同的接口,这样一来,使用这些产品的类可以引用这个接口,而不是具体类。
- 抽象工厂(Creator):实现了所有操纵产品的方法,但不实现工厂方法。Creator所有的子类都必须要实现factoryMethod()方法。
- 具体产品(ConcreteProduct): 实现了factoryMethod(),以实际制造出产品。
- 具体工厂(ConcreteCreator):制造产品的实际工厂。它负责创建一个或者多个具体产品,只有ConcreteCreator类知道如何创建这些产品。
类图
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() );
}
}
运行结果
总结
暂无,继续写下文