设计模式之四:工厂模式(简单工厂、工厂方法、抽象工厂)
2013-05-25 16:04
781 查看
《Head First设计模式》第四章学习笔记
一、设计原则
要依赖抽象,不要依赖具体类。当你直接实例化一个对象时,就是在依赖它的具体类。
如果有一个不像是会改变的类,那么在代码中直接实例化具体类也就没什么大碍。
二、工厂模式
<一>、简单工厂模式
简单工厂模式:就是由一个类的方法(可以是静态方法)根据传入的参数,决定创建出哪一种具体产品类的实例。
简单工厂其实不是一个设计模式,反而比较像是一种编程习惯。类图如下:
<二>、工厂方法模式
工厂方法模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
带参数的工厂方法,称为参数化工厂方法,它可以根据传入的参数创建不同的对象。(不推荐参数化的工厂方法,因为会导致每个具体的方法实现,跟简单工厂是一样的)
工厂方法类图如下:
抽象工厂类Creator,定义了一个创建对象的抽象方法factoryMethod,在每个具体的工厂类中,实现该方法,创建具体的产品实例。
<三>、抽象工厂模式
抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不明确指定具体类。类图如下:
抽象工厂的每个方法,实际上看起来就是工厂方法。
三、例子
1、简单工厂模式的例子
披萨店做披萨,Pizza为披萨抽象类,CheesPizza、GreekPizza、ClamPizza等为具体的Pizza实现类。现在借助简单工厂模式,根据不同的参数,创建不同的披萨。代码片段如下:
简单工厂SimplePizzaFactory类:
PizzaStore类(客户端):
测试代码:
2、工厂方法模式的例子
不同地区的披萨店,做的Pizza不一样。在工厂方法模式中,PizzaStore负责定义创建Pizza的方法,但方法的具体实现,由各个地区的披萨店来实现,并负责创建具体的Pizza。
抽象的工厂类:
具体的工厂类:
具体的工厂类:
测试例子:
3、抽象工厂的例子
4、JDK中工厂模式的应用
简单工厂:
java.lang.Boolean#valueOf(String)
java.lang.reflect.Proxy#newProxyInstance()
java.lang.Class#forName()
java.lang.Class#newInstance()
工厂方法:
java.lang.Object#toString()
四、小结
1、在简单工厂模式中,一个工厂类处于对产品类实例化的中心位置上,它知道每一个产品,它决定哪一个产品类应当被实例化。这个模式的优点是允许客户端相对独立于产品创建的过程,并且在系统引入新产品的时候无需修改客户端,也就是说,它在某种程度上支持“开--闭”原则。但这个模式的缺点是对“开--闭”原则的支持力度不够,因为如果有新的产品加入到系统中去,就需要修改工厂类,将必要的逻辑加入到工厂类中。
2、在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。工厂方法模式退化后可以变得很像简单工厂模式:设想如果非常确定一个系统只需要一个具体工厂类,那么就不妨把抽象工厂给合并到具体的工厂类中。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。
参考资料:
1、《Head First设计模式》
2、《java与模式》
3、JDK里的设计模式
一、设计原则
要依赖抽象,不要依赖具体类。当你直接实例化一个对象时,就是在依赖它的具体类。
如果有一个不像是会改变的类,那么在代码中直接实例化具体类也就没什么大碍。
二、工厂模式
<一>、简单工厂模式
简单工厂模式:就是由一个类的方法(可以是静态方法)根据传入的参数,决定创建出哪一种具体产品类的实例。
简单工厂其实不是一个设计模式,反而比较像是一种编程习惯。类图如下:
<二>、工厂方法模式
工厂方法模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
带参数的工厂方法,称为参数化工厂方法,它可以根据传入的参数创建不同的对象。(不推荐参数化的工厂方法,因为会导致每个具体的方法实现,跟简单工厂是一样的)
工厂方法类图如下:
抽象工厂类Creator,定义了一个创建对象的抽象方法factoryMethod,在每个具体的工厂类中,实现该方法,创建具体的产品实例。
<三>、抽象工厂模式
抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不明确指定具体类。类图如下:
抽象工厂的每个方法,实际上看起来就是工厂方法。
三、例子
1、简单工厂模式的例子
披萨店做披萨,Pizza为披萨抽象类,CheesPizza、GreekPizza、ClamPizza等为具体的Pizza实现类。现在借助简单工厂模式,根据不同的参数,创建不同的披萨。代码片段如下:
简单工厂SimplePizzaFactory类:
public class SimplePizzaFactory { public static Pizza createPizza(String type) { Pizza pizza = null; if ("cheese".equals(type)) { pizza = new CheesePizza(); } else if ("greek".equals(type)) { pizza = new GreekPizza(); } else if ("clam".equals(type)) { pizza = new ClamPizza(); } return pizza; } }
PizzaStore类(客户端):
public class PizzaStore { public Pizza orderPizza(String type) { Pizza pizza = SimplePizzaFactory.createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } }
测试代码:
public class PizzaTestDrive { public static void main(String[] args) { PizzaStore store = new PizzaStore(); Pizza pizza = store.orderPizza("cheese"); System.out.println("Ethan ordered a " + pizza.getName()); pizza = store.orderPizza("clam"); System.out.println("Joel ordered a " + pizza.getName()); } }
2、工厂方法模式的例子
不同地区的披萨店,做的Pizza不一样。在工厂方法模式中,PizzaStore负责定义创建Pizza的方法,但方法的具体实现,由各个地区的披萨店来实现,并负责创建具体的Pizza。
抽象的工厂类:
public abstract class PizzaStore { public Pizza orderPizza(String type) { Pizza pizza = createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } // 抽象的方法,由各个子类来实现。此处用的是参数化的工厂方法 protected abstract Pizza createPizza(String type); }
具体的工厂类:
public class ChicagoPizzaStore extends PizzaStore { protected Pizza createPizza(String type) { if ("cheese".equals(type)) { return new ChicagoStyleCheesePizza(); } return null; } }
具体的工厂类:
public class NYPizzaStore extends PizzaStore { protected Pizza createPizza(String type) { if ("cheese".equals(type)) { return new NYStyleCheesePizza(); } return null; } }
测试例子:
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()); pizza = chicagoStore.orderPizza("cheese"); System.out.println("Joel ordered a " + pizza.getName()); } }
3、抽象工厂的例子
4、JDK中工厂模式的应用
简单工厂:
java.lang.Boolean#valueOf(String)
java.lang.reflect.Proxy#newProxyInstance()
java.lang.Class#forName()
java.lang.Class#newInstance()
工厂方法:
java.lang.Object#toString()
四、小结
1、在简单工厂模式中,一个工厂类处于对产品类实例化的中心位置上,它知道每一个产品,它决定哪一个产品类应当被实例化。这个模式的优点是允许客户端相对独立于产品创建的过程,并且在系统引入新产品的时候无需修改客户端,也就是说,它在某种程度上支持“开--闭”原则。但这个模式的缺点是对“开--闭”原则的支持力度不够,因为如果有新的产品加入到系统中去,就需要修改工厂类,将必要的逻辑加入到工厂类中。
2、在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。工厂方法模式退化后可以变得很像简单工厂模式:设想如果非常确定一个系统只需要一个具体工厂类,那么就不妨把抽象工厂给合并到具体的工厂类中。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。
参考资料:
1、《Head First设计模式》
2、《java与模式》
3、JDK里的设计模式
相关文章推荐
- 设计模式学习003——工厂模式(工厂方法、抽象工厂),简单工厂【也叫静态工厂】
- 设计模式解密(2)- 工厂模式(简单工厂、工厂方法、抽象工厂)
- 设计模式:浅析 抽象工厂、工厂方法、简单(静态)工厂 java实现
- 设计模式 - 简单工厂、工厂方法、抽象工厂
- 设计模式: 简单工厂, 工厂方法, 和抽象工厂总结
- Java设计模式之简单工厂、工厂方法和抽象工厂
- 设计模式:对象创建(原型,单例,简单工厂,工厂方法,抽象工厂,生成器)
- 详解设计模式之工厂模式(简单工厂+工厂方法+抽象工厂)
- 设计模式-简单工厂、工厂方法与抽象工厂
- [设计模式] 简单工厂/工厂方法/抽象工厂
- Java设计模式之工厂模式分析【简单工厂、工厂方法、抽象工厂】
- [设计模式](二):工厂模式(简单工厂|静态工程、工厂方法|多工厂、抽象工厂)
- 设计模式:浅析 抽象工厂、工厂方法、简单(静态)工厂 java实现
- 设计模式--简单工厂、工厂方法和抽象工厂
- 设计模式学习之简单工厂(simple facotry)、工厂方法(actory method)、抽象工厂(abstract factory)
- 创建型设计模式之手工打造、简单工厂、工厂方法和抽象工厂(新)
- 设计模式——简单工厂,工厂方法,抽象工厂
- 设计模式 - 工厂模式(简单,工厂方法,抽象工厂)
- Java设计模式之工厂模式(简单工厂、工厂方法、抽象工厂)
- Java设计模式之简单工厂、工厂方法和抽象工厂