工厂模式
简单工厂模式是属于类的创建型模式,又叫做静态工厂方法(StaticFactory Method)模式,简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。
工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态的决定将哪一个类实例化,工厂模式有以下几种形态:
简单工厂(Simple Factory)模式:又称静态工厂方法(Static FactoryMethord)模式。
工厂方法(Factory Method)模式:又称多态性工厂(PolymorphicFactory)模式或虚拟构造子(Virtual Constructor)模式。
抽象工厂(Abstract Factory)模式:又称工具箱(Kit或Toolkit)模式。
简单工厂模式的引进(一般模式)
如有一个农场,生产各种水果,有苹果(Apple)、草莓(Strawberry)、葡萄(Grape);农场的园丁(FruitGardener)要根据客户的需求,提供相应的水果。
/**
* 《Java与模式》(--阎宏博士著)读书笔记
* 工厂模式模式--简单工厂模式--一般模式
* ReadMe: 工厂类角色: 水果园丁,生产水果产品
*/
public class FruitGardener {
/**
* 静态工厂方法
* @param which :具体的产品名称
* @return 一个水果对象
* @throws BadFruitException
*/
public static Fruit factory(String which)throws BadFruitException {
if(which.equalsIgnoreCase("apple")) {
return new Apple();
} else if(which.equalsIgnoreCase("strawberry")) {
return new Strawberry();
} else if(which.equalsIgnoreCase("grape")) {
return new Grape();
} else {
throw newBadFruitException("Bad fruit request");
}
}
}
简单工厂模式的一般性结构
使用java接口或则java抽象类
如果模式所产生的具体产品类彼此之间没有共同的商业逻辑,那么抽象产品角色可以由一个java接口扮演。相反,如果这些具体产品类彼此之间缺失有共同的商业逻辑,那么这些公有的逻辑就应当移到抽象角色里面,这就意味着抽象角色应当由一个抽象类扮演。
简单工厂模式的一般性结构
简单工厂模式是类的创建模式,这个模式的一般性结构如下图所示。
简单工厂模式就是由一个工厂类根据传入的参量决定创建出哪一种产品类的实例。
简单工厂模式涉及到工厂角色、抽象产品角色和具体产品角色等三个角色。
l 工厂类角色:该角色是工厂方法模式的核心,含有与应用紧密相关的商业逻辑。工厂类在客户端的直接调用下创建产品对象,一般是由具体JAVA实现。当具体产品彼此之间没有太多共同的商业逻辑时就用接口实现。当具体产品间有共同的商业逻辑就用抽象类。
l 抽象产品角色:这个角色的类是由工厂方法模式所创建的对象的父类,或是它们共同拥有的接口。抽象产品角色可以用一个JAVA接口或JAVA抽象类实现
l 具体产品角色:工厂方法模式所创建的对象都是这个角色的实例,由一个具体JAVA实现。
多个工厂方法
分别负责创建不同的产品对象,比如java.text.DateFormat类是其子类的工厂类,而DateFormat类就是提供了多个静态工厂方法。
抽象产品角色的省略
如果系统仅有一个具体产品角色产品角色的话,那么就可以省略掉抽象产品角色。省略掉抽象产品角色后的简略类图如下:
工厂角色与抽象角色合并
在有些情况下,工厂角色可以由抽象产品角色扮演。典型的应用就是java.text.DateFormat类,一个抽象产品类同时是子类的工厂,如下图所示:
三个角色全部合并
如果在上面例子的基础上,连抽象产品角色都省略了,而工厂角色就可以与具体产品角色合并。换言之,一个产品类为自身的工厂。如下图所示:
/**
* 《Java与模式》(--阎宏博士著)读书笔记
* 工厂模式--简单工厂模式--三色合一模式
* ReadMe: 抽象产品,产品,工厂类 三和一后的具体产品类
*/
public class ConcreteProduct
{
public ConcreteProduct(){}
/**
* 静态工厂方法
* @return 具体的产品ConcreteProduct实例
*/
public static ConcreteProduct factory()
{
return new ConcreteProduct();
}
}
简单工厂模式的优点
核心式工厂类,工厂类决定在什么情况下创建哪一种产品类的实例。而客户端则可以免除直接创建产品对象的责任,而仅仅是“消费”产品。简单工厂模式通过这种做法实现了对责任的分割。
简单工厂模式的缺点
当产品类具有复杂的多层次等级结构时,工厂类只有它自己。以不变应万变,是其缺点。
这个工厂类集中了所有产品创建逻辑,形成了一个无所不知的全能类(也称上帝类),如果此类出问题了,整个应用都受大影响。
当产品有多个接口时,判断在什么条件下创建什么产品类实例会很困难。
对于工厂来说,增加新的产品是一个痛苦的过程。工厂角色必须知道每一种产品,如何创建它们,以及何时向客户提供它们。换言之,接纳新的产品意味着修改这个工厂角色的源代码。简单工厂只在有限的程度上支持“开-闭”原则。
由于简单工厂模式使用静态方法作为工厂方法,而静态方法无法由子类继承,因此工厂角色无法形成基于继承的等级结构。这一缺点会在工厂方法模式中得到克服。
“开-闭原则”
“开-闭”原则要求一个系统的设计能够允许系统在无需修改的情况下,扩展其功能。功能的扩展体现在引进新的产品上。“开-闭”原则要求系统允许当新的产品加入系统中时,而无需对现有代码进行修改。这一点对于产品的消费角色是成立的,而对于工厂角色是不成立的。