工厂模式(factory pattern) 详解2016-03-25工厂方法模式: 定义了一个创建对象的接口, 但由子类决定要实例化的类是哪一个. 工厂方法让类把实例化推迟到子类.包括:创建者父类(creator), 包含创建对象的方法(代替new具体的对象, 通过参数创建不同的对象), 和一些基本的方法;具体创建者(concrete creator), 继承创建者父类, 实现创建对象的方法, 不同参数可以创建不同的对象;产品类父类(product), 包含产品的基本使用方法, 被创建者父类(creator)的基本方法使用;具体产品(concrete creator), 继承产品类父类, 对特定的产品进行定制, 供具体创建者(concrete creator)选择创建;具体方法:1. 产品类父类(product), 包含产品的一些基本方法.代码:
/*** @time 2014年5月26日*/package factory;import java.util.ArrayList;/*** @author C.L.Wang**/public abstract class Pizza {String name;String dough; //生面团String sauce; //调味汁ArrayList<String> toppings = new ArrayList<String>(); //装饰void prepare() {System.out.println("Preparing " + name);System.out.println("Tossing dough..." + dough);System.out.println("Adding sauce..." + sauce);System.out.println("Adding toppings: ");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 pizza into diagonal slices");}void box() {System.out.println("Place pizza in official PizzaStore box");}public String getName() {return name;}}
2. 具体产品类(concrete product), 具体产品的定制方法.代码:
/*** @time 2014年5月26日*/package factory;/*** @author C.L.Wang**/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");}}/*** @time 2014年5月26日*/package factory;/*** @author C.L.Wang**/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");}void cut() {System.out.println("Cutting the pizza into square slices");}}
3. 创建者父类(creator), 具体的使用方法, 调用产品类父类(product)的方法, 提供根据参数创建不同具体产品类(concrete product).代码:
/*** @time 2014年5月26日*/package factory;/*** @author C.L.Wang**/public abstract class PizzaStore {public Pizza orderPizza(String item) {Pizza pizza;pizza = createPizza(item);pizza.prepare();pizza.bake();pizza.cut();pizza.box();return pizza;}abstract Pizza createPizza(String item);}
4. 具体创建者(concrete creator), 通过参数创建不同的具体产品(concrete product).代码:
/*** @time 2014年5月26日*/package factory;/*** @author C.L.Wang**/public class NYPizzaStore extends PizzaStore {/* (non-Javadoc)* @see factory.PizzaStore#createPizza(java.lang.String)*/@OverridePizza createPizza(String item) {// TODO Auto-generated method stubif (item.equals("cheese")) {return new NYStyleCheesePizza();} else return null;}}/*** @time 2014年5月26日*/package factory;/*** @author C.L.Wang**/public class ChicagoPizzaStore extends PizzaStore {/* (non-Javadoc)* @see factory.PizzaStore#createPizza(java.lang.String)*/@OverridePizza createPizza(String item) {// TODO Auto-generated method stubif (item.equals("cheese")) {return new ChicagoStyleCheesePizza();} else return null;}}
5. 测试, 创建不同的具体创建者(concrete creator), 即工厂, 通过调用函数的参数, 选择不同的产品进行使用.代码:
/*** @time 2014年5月26日*/package factory;/*** @author C.L.Wang**/public class PizzaTestDrive {/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubPizzaStore nyStore = new NYPizzaStore();PizzaStore chicagoStore = new ChicagoPizzaStore();Pizza pizza = nyStore.orderPizza("cheese");System.out.println("Ethan ordered a " + pizza.getName() + "
");pizza = chicagoStore.orderPizza("cheese");System.out.println("Joel ordered a " + pizza.getName() + "
");}}
6. 输出:
Preparing NY Style Sauce and Cheese PizzaTossing dough...Thin Crust DoughAdding sauce...Marinara SauceAdding toppings:Grated Reggiano CheeseBake for 25 minutes at 350Cutting the pizza into diagonal slicesPlace pizza in official PizzaStore boxEthan ordered a NY Style Sauce and Cheese PizzaPreparing Chicago Style Deep Dish Cheese PizzaTossing dough...Extra Thick Crust DoughAdding sauce...Plum Tomato SauceAdding toppings:Shredded Mozzarella CheeseBake for 25 minutes at 350Cutting the pizza into square slicesPlace pizza in official PizzaStore boxJoel ordered a Chicago Style Deep Dish Cheese Pizza
面向对象的设计原则:依赖倒置原则: 要依赖抽象, 不要依赖具体类.指导方针:1. 变量不可以持有具体类的引用.2. 不要让类派生自具体类.3. 不要覆盖基类中已实现的方法.