1. 为什么需要工厂模式
1.初始化对象经常造成耦合问题,因为当使用“new”时,用的是实现,而不是接口。
(设计原则:针对接口编程,不针对实现编程)
2.工厂处理创建对象的环节。
public abstract class PizzaStore {
public Pizza orderPizza(String type) {
Pizza pizza;
//creatPizza()方法从工厂对象移回PizzaStore
pizza = creatPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
//将工厂对象移到这个方法中
public abstract Pizza creatPizza(String type);
}
4.将一个orderPizza()
方法和一个工厂方法联和起来,就可以成为一个框架。
5.加盟店可以从PizzaStore
免费取得所有的功能,只需要继承PizzaStore
就可以了。
6.对象组合可以在运行时动态改变行为,这样可以更换不同的实现。
2.正确的做法
1.将实例化具体类的代码从应用中抽离,或者封装起来,是它们不会干扰应用的其他部分。(剥离变化的部分)
2.Pizza pizza = new Pizza();
为了让系统有弹性,Pizza
应该为一个抽象类或者接口。
3.让每个域类型(各个子加盟店)都继承上面这个PizzaStore
模板,由各个加盟店决定如何制作Pizza。
4.每个子类都有自己的披萨变体,而仍然适合PizzaStore
框架。并使用调试好的orderPizza()
方法。
5.由于PizzaStore
是抽象的,orderPizza()
并不知道哪些实际的具体类参与进来了,这就是解耦。
6.将一个orderPizza()
方法和一个工厂方法联和起来,就可以成为一个框架。
3.工厂模式
工厂方法模式定义了一个创建对象的接口,但由子类决定实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
将创建对象的代码集中在一个对象或方法中,可以避免代码中的重复,且更方便以后的维护。这样客户实例化对象时,只会依赖于接口,而不是具体类。这可以帮助我们针对接口编程,而不是针对实现编程。
抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指出具体类。
4. 举例
美国一家Pizza连锁店设计一套系统,为自己的加盟商设计订餐系统。有如下特点:
1.每个连锁店的菜单有区别,比如都输入“Cheese”,每个连锁店的CheesePizza就不一样。
2.每个连锁店的原料有区别,比如都输入“Suger”,每个连锁店Suger做法就不一样。
下面是具体测试的代码,先从这里分析:
方法执行的链条:
类的继承和依赖:
类的依赖分析:
5.具体代码
代码有点多,就不全贴在这里了。下面只贴部分主要代码:
public class PizzaTestDrive {
public static void main(String args[]) {
PizzaStore nyStore = new NYPizzaStore();
//PizzaStore chicagoStore = new ChicagoPizzaStore();
Pizza pizza = nyStore.orderPizza("cheese");
//orderPizza() -> NYPizzaStore.creatPizza() -> CheesePizza() -》 prepare() -》ingredientFactory.createDough()等
System.out.println("Ethan ordered a " +pizza.getName() + "\n");
// pizza = chicagoStore.orderPizza("cheese");
// System.out.println("Forever ordered a " +pizza.getName() + "\n");
}
}
public abstract class PizzaStore {
public Pizza orderPizza(String type) {
Pizza pizza;
//creatPizza()方法从工厂对象移回PizzaStore
pizza = creatPizza(type);
//CheesePizza(ingredientFactory)里面重写了prepare()方法
/*
*
public class CheesePizza extends Pizza{
PizzaIngredientFactory ingredientFactory;
public CheesePizza(PizzaIngredientFactory ingredientFactory) {
this.ingredientFactory = ingredientFactory;
}
protected void prepare() {
System.out.println("Preparing " + name);
dough = ingredientFactory.createDough();
sauce = ingredientFactory.createSauce();
cheese = ingredientFactory.createcheese();
}
}
*/
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
//将工厂对象移到这个方法中
public abstract Pizza creatPizza(String type);
}
package BasePackage;
import java.util.ArrayList;
public abstract class Pizza {
public String name; //名称
//public String dough; //面团类型
//public String sauce; //作料
protected Dough dough;
protected Sauce sauce;
Veggies veggies[];
protected Cheese cheese;
Pepperoni pepperoni;
Clams clam;
public ArrayList<String> toppings = new ArrayList<String>();
//提供某些默认的基本做法,包括烘焙、切片和装盒
protected void prepare() {
System.out.println("Preparing "+name);
System.out.println("Tossing dough... ");
System.out.println("Adding sauce...");
System.out.println("Adding topings:");
for(int i = 0; i < toppings.size(); i++) {
System.out.println(" " + toppings.get(i));
}
}
void bake() {
System.out.println("Bake for 25 minutes at 350.");
}
void cut() {
System.out.println("Cutting the pizze into diagonal slices.");
}
void box() {
System.out.println("Place pizza in official PizzaStore box.");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package PizzaStore;
import BasePackage.Pizza;
import BasePackage.PizzaStore;
import IngredientFactory.CheesePizza;
import IngredientFactory.ClamPizza;
import IngredientFactory.NYPizzaIngredientFactory;
import IngredientFactory.PepperoniPizza;
import IngredientFactory.PizzaIngredientFactory;
import IngredientFactory.VeggiePizza;
public class NYPizzaStore extends PizzaStore{
//这里只有creatPizza()方法, Pizza orderPizza(String type) 方法没列出来
public Pizza creatPizza(String item) {
Pizza pizza = null;
PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();
if(item.equals("cheese")) {
pizza = new CheesePizza(ingredientFactory);
pizza.setName("New York Style Cheese Pizza!");
//return new NYStyleCheesePizza();
}else if(item.equals("veggie")) {
pizza = new VeggiePizza(ingredientFactory);
pizza.setName("New York Style Veggie Pizza!");
//return new NYStyleVeggiePizza();
}else if(item.equals("clam")) {
pizza = new ClamPizza(ingredientFactory);
pizza.setName("New York Style Clam Pizza!");
//return new NYStyleClamPizza();
}else if(item.equals("pepperoni")) {
pizza = new PepperoniPizza(ingredientFactory);
pizza.setName("New York Style Pepperoni Pizza!");
//return new NYStylePepperoniPizza();
}else return null;
return pizza;
}
}
运行环境:Eclipse 代码:Java
下载地址
提取码:a1b6