一、工厂模式二、示例 披萨项目:有一家披萨店,有很多种口味的披萨,但是这些披萨除了准备工作不同,后续的烘焙,切割,打包等方法都是相同的 用传统的面向对象模式,则在用户订单类中根据不同的订单要求,生产出不同的披萨 /** * 披萨抽象对象,实现公共方法,抽象差异化的方法 */ public abstract class Pizza { protected String name; public abstract void prepare(); public void bake() { System.out.println(name + " baking;"); } public void cut() { System.out.println(name + " cutting;"); } public void box() { System.out.println(name + " boxing;"); } public void setname(String name) { this.name = name; } } /** * 披萨订单类,OO模式,统一在订单类中进行分类生产 */ public class OrderPizza { public OrderPizza() { Pizza pizza = null; String ordertype; do { ordertype = gettype(); if (ordertype.equals("cheese")) { pizza = new CheesePizza(); } else if (ordertype.equals("greek")) { pizza = new GreekPizza(); } else if (ordertype.equals("pepper")) { pizza = new PepperPizza(); } else if (ordertype.equals("chinese")) { pizza = new ChinesePizza(); } else { break; } pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } while (true); } private String gettype() { try { BufferedReader strin = new BufferedReader(new InputStreamReader( System.in)); System.out.println("input pizza type:"); String str = strin.readLine(); return str; } catch (IOException e) { e.printStackTrace(); return ""; } } } 缺点:无清晰的模块分离,生产与使用方法混在一起
三、简单工厂模式
定义了一个创建对象的类,由这个类来封装实例化对象的行为 /** * 简单工厂模式,将生产方法抽离出单独的类进行生产 */ public class SimplePizzaFactory { public Pizza CreatePizza(String ordertype) { Pizza pizza = null; if (ordertype.equals("cheese")) { pizza = new CheesePizza(); } else if (ordertype.equals("greek")) { pizza = new GreekPizza(); } else if (ordertype.equals("pepper")) { pizza = new PepperPizza(); } return pizza; } } 将生产方法单独用一个类处理,进行简单的模块分离
缺点:不利于拓展多个不同的工厂方法
四、工厂方法模式
定义了一个创建对象的抽象方法,由子类决定要实例化的类。 披萨项目中,若在各地开了分店,但是每个地区的人喜好不同,因此就得区分不同的工厂进行生产。
利用工厂方法模式将对象的实例化抽象到了子类,利用对象之间的继承关系实现差异的工厂方法 /** * 工厂方法对象,给不同的工厂继承 */ public abstract class OrderPizza { public OrderPizza() { Pizza pizza = null; String ordertype; do { ordertype = gettype(); pizza = createPizza(ordertype); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } while (true); } abstract Pizza createPizza(String ordertype); private String gettype() { try { BufferedReader strin = new BufferedReader(new InputStreamReader( System.in)); System.out.println("input pizza type:"); String str = strin.readLine(); return str; } catch (IOException e) { e.printStackTrace(); return ""; } } } /** * 伦敦工厂,继承工厂方法对象 */ public class LDOrderPizza extends OrderPizza { @Override Pizza createPizza(String ordertype) { Pizza pizza = null; if (ordertype.equals("cheese")) { pizza = new LDCheesePizza(); } else if (ordertype.equals("pepper")) { pizza = new LDPepperPizza(); } return pizza; } } /** * 纽约工厂,继承工厂方法对象 */ public class NYOrderPizza extends OrderPizza { @Override Pizza createPizza(String ordertype) { Pizza pizza = null; if (ordertype.equals("cheese")) { pizza = new NYCheesePizza(); } else if (ordertype.equals("pepper")) { pizza = new NYPepperPizza(); } return pizza; } } 需要使用哪种工厂就初始化哪种
OrderPizza mOrderPizza = new NYOrderPizza(); 缺点:继承关系使对象之间的依赖性较高
五、抽象工厂模式
定义了一个接口用于创建相关或有依赖关系的对象族,而无需明确 指定具体类 1.定义一个工厂的接口方法
/** * 工厂方法的抽象接口 */ public interface AbsFactory { public Pizza CreatePizza(String ordertype) ; } 2.各工厂实现工厂方法
/** * 伦敦工厂实现抽象方法 */ public class LDFactory implements AbsFactory { @Override public Pizza CreatePizza(String ordertype) { Pizza pizza = null; if (ordertype.equals("cheese")) { pizza = new LDCheesePizza(); } else if (ordertype.equals("pepper")) { pizza = new LDPepperPizza(); } return pizza; } } 3.利用抽象接口在统一订单对象中进行方法调用
/** * 抽象工厂模式,直接利用抽象工厂进行对象生产 */ public class OrderPizza { // 抽象接口 AbsFactory mFactory; public OrderPizza(AbsFactory mFactory) { setFactory(mFactory); } public void setFactory(AbsFactory mFactory) { Pizza pizza = null; String ordertype; this.mFactory = mFactory; do { ordertype = gettype(); pizza = mFactory.CreatePizza(ordertype); if (pizza != null) { pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } } while (true); } private String gettype() { try { BufferedReader strin = new BufferedReader(new InputStreamReader( System.in)); System.out.println("input pizza type:"); String str = strin.readLine(); return str; } catch (IOException e) { e.printStackTrace(); return ""; } } } 4.使用哪种工厂就进行哪种工厂的初始化
/** * 抽象工厂模式,不同的工厂实现不同的生产方法 * 引用工厂的时候直接引用接口对象 */ public class PizzaStroe { public static void main(String[] args) { OrderPizza mOrderPizza; mOrderPizza=new OrderPizza(new LDFactory()); } } 优点:利用接口进行方法抽象,对象之间耦合度较低,又可实现同种方法内部不同的处理方式。 - 依赖抽象原则
- 变量不要持有具体类的引用
- 不要让类继承自具体类,要继承自抽象类或接口
- 不要覆盖基类中已实现的方法
|