工厂模式
来源:互联网 发布:bbs网络上什么意思 编辑:程序博客网 时间:2024/06/06 00:03
前言
烘烤OO的精华,除了new操作符之外,还有更多制造对象的方法。
工厂方法用来处理对象的创建,并将这样的行为封装在子类中。这样,客户程序中关于超类的代码就和子类对象创建代码解耦了。
简单工厂
简单工厂其实不是一个设计模式,反而比较像是一种编程习惯。
工厂factory处理创建对象的细节,一旦有了SimplePizzaFactory,orderPizza()就变成了此对象的客户。
public class SimplePizzaFactory{ public Pizza createPizza(String type){ Pizza pizza = null; if(type.equals("cheese")){ pizza = new CheesePizza(); } else{ pizza = new VeggiePizza(); } return pizza; }}
把创建Pizza的代码包装进一个类,当以后实现改变时,只需要修改这个类即可。
public class PizzaStore{ SimplePizzaFactory simplePizzaFactory; public PizzaStore(SimplePizzaFactory simplePizzaFactory){ this.simplePizzaFactory = simplePizzaFactory; } public Pizza orderPizza(String type){ Pizza pizza; pizza = simplePizzaFactory.createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; }}
- PizzaStore——这是工厂的“客户“,PizzaStore现在通过SimplePizzaFactory取得Pizza的实例。
- SimplePizzaFactory——这是创建Pizza的”工厂“,唯一用到具体Pizza类的地方。创建方法通常申明为静态。
- Pizza——这是工厂的”产品“ ,把Pizza定义为抽象类,具有一些有用的实现,这些实现可以被覆盖。
- CheesePizza、VeggiePizza、ClamPizza、PepperoniPizza是”具体产品“,每个产品都必须实现Pizza接口。
接下来登场的是两个重量级的模式,它们都是工厂。
”实现一个接口“泛指”实现某个超类型(类或接口)的某个方法“
工厂方法模式
最开始的思路:
NYPizzaFactory nyFactory = new NYPizzaFactory();
PizzaStore nyStore = new PizzaStore(nyFactory);
nyStore.orderPizza(“Veggie”);
新的思路:
把加盟店和创建Pizza捆绑在一起的同时又保持一定的弹性。所要做的事情,就是把createPizza()方法放回到PizzaStore中,不过要把工厂方法设置成”抽象方法“,然后为每个区域风味创建一个PizzaStore的子类。
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里,“工厂方法”现在是抽象的}
允许子类做决定:
- 每个子类都会覆盖createPizza方法,同时使用PizzaStore定义的orderPizza()方法。甚至可以把orderPizza()方法声明为final,以防止被子类覆盖。
- PizzaStore的createPizza()是一个抽象方法,所以任何的具体Pizza子类型“必须实现这个方法”
- NYStylePizzaStore的createPizza()方法会建立纽约风味的Pizza。
public class NYPizzaStore extends PizzaStore{ Pizza createPizza(String item){ if(item.equals("cheese")){ return new NYStyleCheesePizza(); } else return null; }}
说明:
- createPizza()返回一个Pizza对象,由子类全权负责该实例化哪个具体的Pizza。
- NYPizzaStore扩展自PizzaStore,所以拥有orderPizza()方法以及其他的方法。
- 我们必须实现createPizza()方法,因为在PizzaStore里它是抽象的
声明一个工厂方法:
public abstract class PizzaStore{ public Pizza orderPizza(String type){ Pizza pizza; pizza = createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } protected abstract Pizza createPizza(String type);}abstract Product factoryMethod(String type)
- 工厂方法是抽象的,所以依赖子类来处理对象的创建
- 工厂方法必须返回一个产品。超类中定义的方法,通常使用到工厂方法的返回值。
- 工厂方法将客户和实际创建具体产品的代码分割开来。
- 工厂方法可能需要参数,也可能不需要来指定所要的产品。
新版工厂方法订购Pizza
PizzaStore nyPizzaStore = new NYPizzaStore();//纽约披萨店
nyPizzaStore.orderPizza("cheese");//下订单
Pizza pizza = createPizza("cheese");//orderPizza调用create方法
- 最后经过prepare、bake、cut、box处理完成。
public abstract class Pizza {//披萨本身 String name; String dough; String sauce; ArrayList toppings = new ArrayList(); void prepare(){ } void bake(){ } void cut(){ } void box(){ } public String getName(){ return name; }}
public class NYStyleCheesePizza extends Pizza{ public NYStyleCheesePizza(){ name = "NY Style"; dough = "Thin Crust"; sauce = "Marinara"; toppings.add("Reggiano"); }}
整体认识工厂方法模式
所有工厂模式都用来封装对象的创建,工厂方法模式Factory Method Pattern通过让子类决定该创建的对象是什么,来达到将对象创建的过程封装的目的。
我们可以看到,将一个orderPizza()方法和一个工厂方法联合方法,就可以成为一个框架。除此之外,工厂方法将生产知识封装进各个创建者,这样的做法也可以被视为一个框架。
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
Product——所有的产品必须实现这个共同的接口,这样一来,使用这些产品的类就可以引用这个接口,而不是具体类。
Creator——Creator是一个类,它实现了所有操纵产品的方法,但不实现工厂方法。Creator所有的子类必须实现这个抽象的factoryMethod()方法。
抽象工厂模式
抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
比萨店的设计变得很棒:具有弹性的架构,而且遵循设计原则。
原料家族:纽约使用一组原料,而芝加哥使用另一组原料……
public interface PizzaIngredientFactory{ public Dough createDough(); public Sauce createSauce(); public Cheese createCheese(); public Veggies[] createVeggies(); public Pepperoni createPepperoni(); public Clams createClam();}//如果每个工厂实例内部都有某一种通用的“机制”需要实现,就可以把这个例子改成抽象类。
创建纽约的原料工厂
public class NYPizzaIngredientFactory implements PizzaIngredientFactory{ public Dough createDough(){ return new ThinCrustDough(); } public Sauce createSauce(){ return new MarinaraSauce(); } public Cheese createCheese(){ return new ReggianoCheese(); } public Veggies[] createVeggies(){ Veggies veggies[] = { new Garlic(),new Onion()}; return veggies; } public Pepperoni createPepperoni(){ return new SlicedPepperoni(); } public Clams createClam(){ return new FreshClams(); }}
重做比萨……
public abstract class Pizza {//披萨本身 String name; Dough dough; Sauce sauce; Veggies veggies[]; Cheese cheese; Pepperoni pepperoni; Clams clam; abstract void prepare(); void bake(){ } void cut(){ } void box(){ } public String getName(){ return name; }}
继续重做比萨……
public class CheesePizza extends Pizza{ PizzaIngredientFactory pizzaIngredientFactory; public CheesePizza(PizzaIngredientFactory pizzaIngredientFactory){ this.pizzaIngredientFactory = pizzaIngredientFactory; } void prepare(){ dough = pizzaIngredientFactory.createDough(); sauce = pizzaIngredientFactory.createSauce(); cheese = pizzaIngredientFactory.createCheese(); }}
再回到比萨店
public class NYPizzaStore extends PizzaStore{ protected Pizza createPizza(String item){ Pizza pizza = null; PizzaIngredientFactory pizzaIngredientFactory = new NYPizzaIngredientFactory(); if(item.equals("cheese")){ pizza = new CheesePizza(pizzaIngredientFactory); pizza.setName("New York Style Cheese Pizza"); } else return null; return pizza; }}
- 工厂模式 -- 工厂方法
- 工厂模式 -- 抽象工厂
- 工厂模式-简单工厂
- 工厂模式-工厂方法
- 工厂模式:静态工厂
- 工厂模式-简单工厂
- 工厂模式-抽象工厂
- 工厂模式-工厂方法
- 工厂 > 工厂方法模式
- 工厂模式-静态工厂
- 工厂模式-抽象工厂
- 工厂模式
- 工厂模式
- 工厂模式
- 工厂模式
- 工厂模式
- 工厂模式
- 工厂模式
- cprintf
- Android中使用AIDL完成不同进程间的通信
- 发送功率定义
- Practical Deep Text Learning
- java web环境搭建
- 工厂模式
- 韩信点兵
- 怎样解决PHP中文乱码问题
- android——倒计时实现
- sqlplus执行代码块 包含代码块的sql文件
- AWS和Azure的比较(2)
- Oracle同义词创建及其作用
- Linux命令大全
- 《FAQ:OpenCV Haartraining》——使用OpenCV训练Haar like+Adaboost分类器的常见问题