一、简单工厂模式的定义(单机版)
如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫“简单工厂模式”,
它不属于 GoF 的 23 种经典设计模式。
它的缺点是增加新产品时会违背“开闭原则”(可以通过反射克服该缺点)。
二、工厂方法模式的定义(扩展版)
工厂方法模式又称为工厂模式,也叫虚拟构造器模式或者多态工厂模式。
定义一个创建产品对象的工厂接口,让工厂子类决定实例化那一个产品类。工厂方法使一个类的实例化延迟到其子类。
我们把被创建的对象称为“产品”,把创建产品的对象称为“工厂”。
“工厂方法模式”是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则。
三、 工厂方法的模式结构
(1)抽象工厂(Factory)角色:是工厂方法模式的核心,与应用程序无关。提供了创建产品的接口,任何在模式中创建的对象的工厂类必须实现这个接口。
(2)具体工厂(ConcreteCreator)角色:实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。
(3)抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。定义了产品的规范,描述了产品的主要特性和功能。
(4)具体产品(ConcreteProduct)角色:这个角色实现了抽象产品角色所定义的接口。具体产品由专门的具体工厂创建,它们之间往往一一对应。
1. 抽象工厂、抽象产品可以是接口,也可以是抽象类。
2. 抽象产品的定义方式取决于产品对象的建模事物,抽象工厂的定义方式一般与抽象产品的定义方式保持一致。
3. 一般情况下,产品对象是对现实世界中的事物进行建模,使用抽象类定义抽象产品更合理。
4. 特殊情况下,产品对象对功能组件、功能实现建模或产品对象已有父对象(C#中对象只能有一个父类)时则使用接口定义抽象产品。
四、工厂方法的模式示例
抽象工厂类
public interface Factory {
Product factoryMethod();
}
具体工厂类
public class FactoryA implements Factory{
@Override
public Product factoryMethod() {
return new ProductA();
}
}
public class FactoryB implements Factory{
@Override
public Product factoryMethod() {
return new ProductB();
}
}
抽象产品类
public abstract class Product {
public abstract void show();
}
具体产品类
public class ProductA extends Product {
@Override
public void show() {
System.out.println("生产出了A产品");
}
}
public class ProductB extends Product{
@Override
public void show() {
System.out.println("生产出了B产品");
}
}
生产测试
public class FactoryMethod {
public static void main(String[] args) {
Factory factoryA = new FactoryA();
Product productA = factoryA.factoryMethod();
productA.show();
Factory factoryB = new FactoryB();
Product productB = factoryB.factoryMethod();
productB.show();
}
}
五、工厂方法的优缺点
1.优点
(1)用户只需要关心所需产品对应的工厂,无须关心创建细节。
(2)基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够使工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,是因为所有的具体工厂类都具有同一抽象父类。
(3)在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了。这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”。
2.缺点:
(1)在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
(2)由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度。
六、工厂方法的总结
工厂方法模式是简单工厂模式的进一步抽象和推广。
工厂方法模式不但保持了简单工厂模式的优点,而且克服了它的缺点。
在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去做。
这个核心类仅仅负责给出具体工厂必须实现的接口,而不负责产品类被实例化这种细节,这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。