- 定义
工厂模式定义了一个创建对象的接口,但由子类决定实例化的类是哪一个。工厂模式方法让类把实例化推迟到子类。 - 案例分析
假设现在有一个比萨店。
Pizza orderPizza(String type){
Pizza pizza ;
if(type.equals("cheese"))
pizza = new CheesePizza();
else if(type.equals("greek"))
pizza = new GreekPizza();
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
但是这样做会有一个问题,那就是当我们需要增加和改变pizza类型时必须修改该部分代码,违反了“对扩展开放,对修改关闭的原则”
所以我们可以这么做,
Pizza PizzaStore{
Simplefactory factory;
public PizzaStore(Simplefactory factory){
this.factory = factory;
}
Pizza orderPizza(String type){
Pizza pizza ;
pizza = factory.createPizza(type)
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
进一步的,如果有多个工厂我们可以如下设计
package org.sxd.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;
}
abstract Pizza createPizza(String type);
}
将PizzaStore设置成抽象类,那么子类就可以继承这个类,从而自定义ccreatePizza方法,依旧是不同的工厂了。
3. 实现
package org.sxd.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;
}
abstract Pizza createPizza(String type);
}
package org.sxd.factory;
public class PizzaTestDrive {
public static void main(String[] args){
PizzaStore nyStore = new NYPizzaStore();
PizzaStore chicagoStore = new ChicagoPizzaStore();
Pizza pizza = nyStore.orderPizza("cheese");
System.out.println("Ethan ordered a " + pizza.getName() + "\n");
pizza = chicagoStore.orderPizza("cheese");
System.out.println("Joel ordered a " + pizza.getName() + "\n");
}
}
package org.sxd.factory;
public class NYPizzaStore extends PizzaStore{
@Override
Pizza createPizza(String type) {
// TODO Auto-generated method stub
if(type.equals("cheese")){
return new NYStyleCheesePizza();
}
return null;
}
}
package org.sxd.factory;
import java.util.ArrayList;
public class Pizza {
protected String name;
protected String dough;
protected String sauce;
ArrayList toppings = new ArrayList();
protected void prepare(){
System.out.println("Prepareing " + name);
System.out.println("Tossing dough...");
System.out.println("Adding sauce...");
System.out.println("Adding topping: ");
for(int i =0; i < toppings.size(); i++){
System.out.println(" " + toppings.get(i));
}
}
protected void bake(){
System.out.println("Bake for 25 minutes at 350");
}
protected void cut(){
System.out.println("Cutting the pizza into diagonal slices");
}
protected void box(){
System.out.println("Please pizza in offical PizzaStore Box");
}
public String getName(){
return name;
}
}
package org.sxd.factory;
public class ChicagoStyleCheesePizza extends Pizza{
public ChicagoStyleCheesePizza(){
name = "Chicago Style Deep Dish Cheese Pizza";
dough = "Extra Thick Crust Dough";
sauce = "Plum Tomato Sauce";
toppings.add("Shredded Mozzarella Cheese");
}
protected void cut(){
System.out.println("Cutting the pizza into square slices");
}
}
package org.sxd.factory;
public class ChicagoPizzaStore extends PizzaStore{
@Override
Pizza createPizza(String type) {
// TODO Auto-generated method stub
if(type.equals("cheese")){
return new ChicagoStyleCheesePizza();
}
return null;
}
}
package org.sxd.factory;
public class NYStyleCheesePizza extends Pizza{
public NYStyleCheesePizza(){
name = "NY Style Sauce and Cheese Pizza";
dough = "Thin Crust Dough";
sauce = "Marinara Sauce";
toppings.add("Grated Reggiano Cheese");
}
}