一、工厂模式诞生背景
艺术源于生活,技术亦是。不管是艺术,还是技术,都是人们的思想产物。
生活中,我们使用(吃喝住行)的绝大部分事物都不是我们自己亲手制造的,而是由工厂批量制作出来,我们直接使用成品(或自己组装成成品),我们并不需要知道这些事物的制作细节。设想一下,如果我们使用的每一样事物都需要我们自己制作出来,这是多么恐怖的一件事情!
同样,在代码世界里,调用者使用的每一个对象都要自己创建出来,这很繁琐而且耦合性高。在此背景下,工厂模式应运而生,该模式的使命就是将对象的创建和使用分离开来。
目前看来,共有3种工厂模式可供参考:简单工厂模式、工厂方法模式以及抽象工厂模式。
二、简单工厂模式
由工厂对象决定创建哪一种产品类的实例。
简单工厂模式适用于工厂类需要创建对象较少的场景,客户端只需要传入工厂类的参数。
该模式将产品抽象出来,例如:
public interface IProduct{
public void tag();
}
通过IProduct接口拓展产品细节,
public interface ProductA{
public void tag() {
System.out.println("I'm ProductA");
}
}
常见的简单工厂模式中,工厂对象通过客户端参数来判断创建哪个产品对象,如:
public class XXXFactory {
public IProduct create(String paraxxx) {
if("xxx".equals(paraxxx)) {
return new PrductA();
}
else if ("xxx2".equals(paraxxx)) {
return new PrductB();
}
}
}
客户端调用方式:
XXXFactory xxxFactory = new XXXFactory();
xxxFactory.create("xxx");
这种情况下,如果新增一种产品ProductC,则必须修改工厂类中的create方法,这违反开闭原则。因此,可以应用反射来创建对象。
例:
public class XXXFactory {
public IProduct create(Class<? extends IProduct> clazz) {
try {
if(null != clazz) {
return clazz.newInstance();
}
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
调用方式
XXXFactory xxxFactory = new XXXFactory();
xxxFactory.create(ProductA.class);
如上所示,简单工厂模式将对象的创建全都交给同一个工厂类(相当于全世界只有一家工厂在生产物品,而物品是多种多样的,生活中也不存在“万能工厂”),工厂类职责相对过重,产品结构复杂的情形下,不易于扩展及维护。
三、工厂方法模式
工厂方法模式,在简单工厂的基础上,对工厂进行抽象,
public interface IFactory{
public IProduct create();
}
工厂跟产品一样,进一步细分,所有工厂都必须实现IFactory接口,而产品的实例化交给子类。
例如ProductA由ProductAFactory去创建,
ProductAFactory implements IFactory{
public IProduct create() {
return new ProductA();
}
}
调用方式
IFactory factory = new ProductAFactory();
factory.create().tag();
由于工厂方法模式对工厂进行了抽象,因此会比简单工厂模式多出抽象工厂类的实现类,当工厂种类多时,编码量较简单工厂模式会大很多。
总之,工厂方法模式相较于简单工厂模式只有一个工厂类而言,分散了工厂类的职责,但同时也增加了代码量。
四、抽象工厂模式
抽象工厂模式是3中模式中最接近现实生活中的工厂模式,学习前先了解两个概念:产品族和产品等级结构。
(1) 产品等级结构:产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。
(2) 产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中,海尔电视机、海尔电冰箱构成了一个产品族。
从这两概念就能看出这真的是直接从现实生活中抽象出来的模式,抽象工厂模式是在工厂方法模式的基础上,又对抽象产品和抽象工厂进行了细分,把他们分成不同品牌的工厂和不同工厂的产品(一个抽象工厂能生产多种抽象产品)。
例:一个工厂能生产两种产品A和B
public interface IFactory{
public IProductA createProductA();
public IProductB createProductB();
}
public interface IProductA{
public void tag();
}
public interface IProductB{
public void tag();
}
张三和李四的工厂都能制造A和B两种产品,
public class ZhangsanFactory implements IFactory {
public IProductA createProductA(){
return new ZhangsanProductA();
}
public IProductB createProductB(){
return new ZhangsanProductB();
}
}
public class ZhangsanProductA implements ProductA{
public void tag(){
System.out.println("I'm ProductA from ZhangsanFactory")
}
}
public class ZhangsanProductB implements ProductB{
public void tag(){
System.out.println("I'm ProductB from ZhangsanFactory")
}
}
...