工厂模式分类:
- 简单工厂:明确地计划不同条件下创建不同实例时;
- 优化后的工厂:同上;
- 抽象工厂:系统的产品有多个的产品 族,而系统只消费其中某一族的产品。
1.简单工厂:
简单工厂适合的场景:
我们需要一辆汽车,可以直接从工厂里面提货。
我们既不用去管这辆汽车是怎么做出来的,也不用知道这个汽车里面的具体实现。
简单工厂的类图:
很明显,SimpleFactories
将负责createPizza(String pizzaName)
,调用者应该使用SimpleFactories
。SimpleFactory
们和Pizza
们之间使用虚线箭头关联,这意味着他们之间的依赖很低。而其中,具体的SimpleFactory
(即SimpleFactoryInKaizhou
)负责真正的Pizza
制造。
本⽂以以上UML实例为例。
具体的SimpleFactory
们的代码:
public class SimpleFactoryInKaizhou implements SimpleFactory {
public Pizza createPizza(String pizzaName) {
Pizza pizza = null;
if (pizzaName.equals("cheese")) {
pizza = new CheesePizza();
} else if (pizzaName.equals("greek")) {
pizza = new GreekPizza();
} else if (pizzaName.equals("pepper")) {
pizza = new PepperPizza();
}
pizza.pizzaName = pizzaName;
return pizza;
}
}
2.优化后的工厂模式:
工厂模式类图:
当前工厂模式的解释:
- 工厂现在贴合语义,变成了
PizzaStore
; - 工厂
PizzaStore
和产品Pizza
变成了关联关系; - 工厂
PizzaStore
仍然承诺负责_createPizza(String pizzaName)_
,但真正创建产品Pizza
的任务交给了工厂PizzaStore
的具体子类; 工厂
PizzaStore
提供了orderPizza(String pizzaName);
来实现所有工厂都将可以提供点餐服务,具体子类将在此生产具体产品。Pizza
们:抽象的
Pizza
:声明作为Pizza的属性及其方法:
public abstract class Pizza {
public String pizzaName; //披萨名字
public String doughName; //面团名字
public String sauceName; //酱料名字
public ArrayList<String> toppingNames = null; //配料名字
public abstract void prepare(); //本实例中,这个方法将充当 构造器 的初始化任务
public abstract void cut();
public abstract void bake();
public abstract void box();
public String toString() {
String ret = "This is a " + pizzaName + " WITH " + doughName + " " + sauceName;
if (toppingNames != null) {
for (String t : toppingNames) {
ret = ret + " " + t;
}
}
return ret;
}
}
KaizhouCheesePizza
:具体的
Pizza
产品,是真正被使用的Pizza
:public class KaizhouCheesePizza extends Pizza {
public void prepare() { //充当构造器
this.pizzaName = "CheesePizza";
this.doughName = "KaizhouDough";
this.sauceName = "KaizhouSauce";
toppingNames = new ArrayList<>();
toppingNames.add("rice");
toppingNames.add("water");
}
public void cut() {
System.out.println("Cutting KaizhouCheesePizza!");
}
public void bake() {
System.out.println("Baking KaizhouCheesePizza!");
}
public void box() {
System.out.println("Boxing KaizhouCheesePizza!");
}
}
工厂类
PizzaStore
们:抽象的
PizzaStore
:这个类将作为工厂的模板,他承诺能够create pizza,但真正的操作将交给它的具体子类实现:
public abstract class PizzaStore { //Store和Factory合并
public Pizza pizza;
public abstract Pizza createPizza(String pizzaName);//具体的制作由具体的店面实现
public Pizza orderPizza(String pizzaName) {//依然负责所有关于处理pizza的事
pizza = this.createPizza(pizzaName);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
KaizhouPizzaStore
:public class KaizhouPizzaStore extends PizzaStore {
public KaizhouPizzaStore() {
System.out.println("\n" + "A KaizhouPizzaStore ready");
}
@Override
public Pizza createPizza(String pizzaName) {
if (pizzaName.equals("cheese")) {
return new KaizhouCheesePizza();
} else if (pizzaName.equals("pepper")) {
return new PepperPizza();
}
return null;
}
}
工厂模式测试代码:
//合并了Store和Factory
//Store就是工厂,对产品的各种操作在Store里,但是 生产产品 在Store的派生类里面
//使用者只知道各种操作存在,但是具体的操作干了什么,在store派生类中被决定,
public class Main {
public static void main(String s[]) {
Pizza pizza;
PizzaStore pizzaStore;
pizzaStore = new KaizhouPizzaStore(); //指定具体工程
pizza = pizzaStore.orderPizza("cheese");
System.out.println(pizza);
}
}
优化的工厂模式的要点:
工厂模式必须提供的能力:
抽象类工厂应该规定子类必须创建对象的方法
_protected abstract Pizza createPizza(String pizzaName);_
;- 抽象类工厂应提供对外的获取产品的方法
public Pizza orderPizza(String pizzaName);
; - 由上,抽象类工厂应规定
orderPizza
具有生产Pizza
的功能:public Pizza orderPizza(String pizzaName) {//依然负责所有关于处理pizza的事
pizza = this.createPizza(pizzaName);
//其他code
}
工厂模式的核心思想:
- 工厂定义一个创建对象的接口,
- 让其 子类自己 决定实例化哪一个工厂类、产生具体哪一个产品;
工厂模式使其创建过程延迟到 子类 进行。