抽象工厂模式
定义:抽象工厂模式隶属于设计模式中的创建型模式,用于产品族的构建。抽象工厂是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂是指当有多个抽象角色时使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象。
抽象工厂模式的优缺点
优点:
- 可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
- 当增加一个新的产品族时不需要修改原代码,满足开闭原则。
缺点:
- 当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改
抽象工厂模式的应用场景
-
一个系统不应当依赖于具体类实例如何被创建、 组合和表达的细节, 这对于所有类型的工厂模式都是很重要的, 用户无须关心对象的创建过程, 将对象的创建和使用解耦;
-
系统中有多于一个的族, 而每次只使用其中某一族。 可以通过配置文件等方式来使得用户可以动态改变族, 也可以很方便地增加新的族。
-
属于同一个族的对象将在一起使用, 这一约束必须在系统的设计中体现出来。 同一个族中的对象可以是没有任何关系的对象, 但是它们都具有一些共同的约束, 如同一操作系统下的按钮和文本框, 按钮与文本框之间没有直接关系, 但它们都是属于某一操作系统的, 此时具有一个共同的约束条件: 操作系统的类型。
-
等级结构稳定, 设计完成之后, 不会向系统中增加新的等级结构或者删除已有的等级结构。
抽象工厂模式的实现
抽象工厂的角色:
-
抽象工厂:声明一组用于创建一族产品的方法,每个方法对应一种对象;在抽象工厂中声明了多个工厂方法, 用于创建不同类型的对象, 抽象工厂可以是接口, 也可以是抽象类或者具体类,具体实现可参考上例中的ShapeFactory;
-
具体工厂:具体工厂实现了抽象工厂,每个工厂方法返回一个具体对象,一个具体工厂所创建的具体对象构成一个族。具体实现可参考上例中的RedShapeFactory;
-
抽象类接口:提供一组所有类都具有的业务方法。
-
抽象类:用于实现抽象接口所定义的业务方法,但是该角色对于抽象接口定义的方法只做抽象实现,即所有实现都被定义为抽象方法,最终的具体实现全部交给具体类实现。引入该角色主要是为了根据声明不同的抽象类,将类区分为不同的等级结构。
-
具体类:该角色继承抽象类,主要用于实现抽象类中声明的抽象方法,完成不同等级结构,不同族的业务方法的具体实现。
案例:畜牧场可以养动物,也可以培养植物。现在A畜牧场可以养马和种植蔬菜,B畜牧场可以养牛和种植水果。
步骤1: 创建抽象工厂类,定义具体工厂的公共接口
public interface AbstractFactory {
Animal newAnimal();
Plant newPlant();
}
步骤2: 创建抽象产品族类 ,定义具体产品的公共接口;
public interface Animal {
void show();
}
public interface Plant {
void show();
}
步骤3: 创建具体产品类(继承抽象产品类), 定义生产的具体产品;
public class Horse implements Animal {
@Override
public void show() {
System.out.println("这是一匹马");
}
}
public class Cattle implements Animal {
@Override
public void show() {
System.out.println("这是一头牛");
}
}
public class Fruitage implements Plant {
@Override
public void show() {
System.out.println("这是水果");
}
}
public class Vegetables implements Plant {
@Override
public void show() {
System.out.println("这是蔬菜");
}
}
步骤4:创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
public class FactoryA implements AbstractFactory {
@Override
public Animal newAnimal() {
return new Horse();
}
@Override
public Plant newPlant() {
return new Vegetables();
}
}
public class FactoryB implements AbstractFactory{
@Override
public Animal newAnimal() {
return new Cattle();
}
@Override
public Plant newPlant() {
return new Fruitage();
}
}
步骤5:客户端通过实例化具体的工厂类,并调用其创建不同目标产品的方法创建不同具体产品类的实例
public class Main {
public static void main(String[] args) {
FactoryA factoryA = new FactoryA();
factoryA.newAnimal().show();
factoryA.newPlant().show();
FactoryB factoryB = new FactoryB();
factoryB.newAnimal().show();
factoryB.newPlant().show();
}
}
结果
这是一匹马
这是蔬菜
这是一头牛
这是水果