一、Simple Factory
简单工厂模式的一般结构图:
[img]http://dl.iteye.com/upload/attachment/227620/63e37245-4fcb-3747-8184-65884510477c.png[/img]
其中,AbstractProduct既可以是Interface也可以是Abstract class.
1.如果把AbstractProduct和ConcreteProduct合并,也就是没有AbstractProduct,那就是最简单的工厂应用,比如swing里面的UIManager.
2.如果把Factory和AbstractProduct合并,由AbstractProduct做两者的事情,那就像DateFormat和SimpleDatFormat.
[img]http://dl.iteye.com/upload/attachment/227561/d7d5b0fc-61fb-3758-a324-f63d18ccb1ac.png[/img]
可以看到Abstract class DateFormat自己就提供了static的方法去获取各种类型的DateFormat实现类,其中就包括SimpleDateFormat.
3.如果来个三合一呢,那就是自己能产生自己的对象,Java里面的Boolean类的valueOf方法就很像这样的效果。
4.如果是三个因素一个都不少呢,concurrent包里面就有现成的案例
[img]http://dl.iteye.com/upload/attachment/227559/257a6126-d840-3119-9bb8-8838436d7dea.png[/img]
优点:
由Factory决定在什么情况下创建哪一种产品类的实例,而使用者则可以免除直接创建产品对象的责任,而仅仅是“消费”产品。
缺点:
对于Factory来说,增加新的产品需要新写一个产品类ConcreteProductB,就需要去修改Factory的具体实现。
SimpleFactory使用static方法作为工厂方法,而static方法无法由子类继承,因此Factory无法形成基于继承的等级结构。
二、Factory Method
其实它就是多态性的Factory.把产生对象的具体动作,下放给具体Factory去执行。
[img]http://dl.iteye.com/upload/attachment/227632/fced44c7-53d5-3a2c-84bf-2d099b0af268.png[/img]
这样做的好处就是:如果需要增加另外的产品比如ConcreteProductC,就仅仅只需要增加对应的FactoryC就可以了。按照比较学术的词汇,就是在同一个产品等级结构内(AbstractProduct接口不变),可以增加任意的新产品(ConcreteProductC),而不需要去改动其他任何Factory(FactoryA FactoryB)代码。
三、Abstract Factory
如果需要对Product进行分类,也就是构造"产品族"这样的概念.
[img]http://dl.iteye.com/upload/attachment/227634/e7248ad4-da2f-36fa-ae6b-f0c90d83d39e.png[/img]
这个方式,增加新的产品族(ConcreteProductA3 ConcreteProductB3 Factory3)非常容易,不需要改变任何类,但是增加一个新的产品等级ProductC,就需要改动所有的Factory了,这是它的缺陷所在。
Factory Method和AbstractFactory在JDK中有个非常典型的应用,就是jaxp.
因为XML的解析器有好几种,jaxp良好的面向接口的设计,使得在不同的XML解析器之间切换,也不需要去改变代码。下面是一个随便写的XML解析过程。
其中DocumentBuilderFactory,DocumentBuilder,Document,Element,Node等对象全部是abstract class.
1. DocumentBuilderFactory类就是图中AbstractFactory的角色,通过newInstance()方法创建了一个DocumentBuilderFactory子类,这就是1.2的SimpleFactory应用,而SimpleFactory其实就是FactoryMethod的简化方式。
2. 这个newInstance得出的DocumentBuilderFactory实例,也就是代码中的dbf,其实是一种XML解析器内的实现子类,dbf充当的是上图中的Factory1或者Factory2的角色
3. dbf调用newDocumentBuilder方法就相当于是Factory1调用createProductA方法,得到的db实例就是DocumentBuilder抽象类子特定XML解析器中的实现类实例。
简单工厂模式的一般结构图:
[img]http://dl.iteye.com/upload/attachment/227620/63e37245-4fcb-3747-8184-65884510477c.png[/img]
其中,AbstractProduct既可以是Interface也可以是Abstract class.
1.如果把AbstractProduct和ConcreteProduct合并,也就是没有AbstractProduct,那就是最简单的工厂应用,比如swing里面的UIManager.
LookAndFeel defaultLookAndFeel = UIManager.getLookAndFeel();
2.如果把Factory和AbstractProduct合并,由AbstractProduct做两者的事情,那就像DateFormat和SimpleDatFormat.
[img]http://dl.iteye.com/upload/attachment/227561/d7d5b0fc-61fb-3758-a324-f63d18ccb1ac.png[/img]
可以看到Abstract class DateFormat自己就提供了static的方法去获取各种类型的DateFormat实现类,其中就包括SimpleDateFormat.
3.如果来个三合一呢,那就是自己能产生自己的对象,Java里面的Boolean类的valueOf方法就很像这样的效果。
Boolean temp = Boolean.valueOf(true);
4.如果是三个因素一个都不少呢,concurrent包里面就有现成的案例
[img]http://dl.iteye.com/upload/attachment/227559/257a6126-d840-3119-9bb8-8838436d7dea.png[/img]
优点:
由Factory决定在什么情况下创建哪一种产品类的实例,而使用者则可以免除直接创建产品对象的责任,而仅仅是“消费”产品。
缺点:
对于Factory来说,增加新的产品需要新写一个产品类ConcreteProductB,就需要去修改Factory的具体实现。
SimpleFactory使用static方法作为工厂方法,而static方法无法由子类继承,因此Factory无法形成基于继承的等级结构。
二、Factory Method
其实它就是多态性的Factory.把产生对象的具体动作,下放给具体Factory去执行。
[img]http://dl.iteye.com/upload/attachment/227632/fced44c7-53d5-3a2c-84bf-2d099b0af268.png[/img]
这样做的好处就是:如果需要增加另外的产品比如ConcreteProductC,就仅仅只需要增加对应的FactoryC就可以了。按照比较学术的词汇,就是在同一个产品等级结构内(AbstractProduct接口不变),可以增加任意的新产品(ConcreteProductC),而不需要去改动其他任何Factory(FactoryA FactoryB)代码。
三、Abstract Factory
如果需要对Product进行分类,也就是构造"产品族"这样的概念.
[img]http://dl.iteye.com/upload/attachment/227634/e7248ad4-da2f-36fa-ae6b-f0c90d83d39e.png[/img]
这个方式,增加新的产品族(ConcreteProductA3 ConcreteProductB3 Factory3)非常容易,不需要改变任何类,但是增加一个新的产品等级ProductC,就需要改动所有的Factory了,这是它的缺陷所在。
Factory Method和AbstractFactory在JDK中有个非常典型的应用,就是jaxp.
因为XML的解析器有好几种,jaxp良好的面向接口的设计,使得在不同的XML解析器之间切换,也不需要去改变代码。下面是一个随便写的XML解析过程。
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db;
try {
db = dbf.newDocumentBuilder();
Document doc = db.parse(new File(""));
Element root = doc.getDocumentElement();
NodeList valueNode = root.getElementsByTagName("value");
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
其中DocumentBuilderFactory,DocumentBuilder,Document,Element,Node等对象全部是abstract class.
1. DocumentBuilderFactory类就是图中AbstractFactory的角色,通过newInstance()方法创建了一个DocumentBuilderFactory子类,这就是1.2的SimpleFactory应用,而SimpleFactory其实就是FactoryMethod的简化方式。
2. 这个newInstance得出的DocumentBuilderFactory实例,也就是代码中的dbf,其实是一种XML解析器内的实现子类,dbf充当的是上图中的Factory1或者Factory2的角色
3. dbf调用newDocumentBuilder方法就相当于是Factory1调用createProductA方法,得到的db实例就是DocumentBuilder抽象类子特定XML解析器中的实现类实例。