产品族与等级结构
产品等级结构:产品等级结构即产品的继承结构。
产品族:产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。
结构
- AbstractFactory(抽象工厂):他申明了一组用于创建一族产品的方法,每一个方法对应一种产品。
- ConcreteFactory(具体工厂):它实现了在抽象工厂中申明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。
- AbstractProduct(抽象产品):它为每种产品申明接口,在抽象产品中声明了产品所具有的业务方法。
- ConcretePorduct(具体产品):它定义具体工厂生产的具体产品对象,实现抽象产品中声明的业务方法。
代码
抽象产品A
public interface ProduceA {
void method();
}
抽象产品B
public interface ProduceB {
void method();
}
具体产品A1
public class ConcreteProduceA1 implements ProduceA {
@Override
public void method() {
System.out.println("ConcreteProduceA1");
}
}
具体产品A2
public class ConcreteProduceA2 implements ProduceA {
@Override
public void method() {
System.out.println("ConcreteProduceA2");
}
}
具体产品B1
public class ConcreteProduceB1 implements ProduceB {
@Override
public void method() {
System.out.println("ConcreteProduceB1");
}
}
具体产品B2
public class ConcreteProduceB2 implements ProduceB {
@Override
public void method() {
System.out.println("ConcreteProduceB2");
}
}
抽象工厂
public interface AbstractFactory {
ProduceA createProduceA();
ProduceB createProduceB();
}
具体工厂1
public class ConcreteFactory1 implements AbstractFactory {
@Override
public ProduceA createProduceA() {
return new ConcreteProduceA1();
}
@Override
public ProduceB createProduceB() {
return new ConcreteProduceB1();
}
}
具体工厂2
public class ConcreteFactory2 implements AbstractFactory {
@Override
public ProduceA createProduceA() {
return new ConcreteProduceA2();
}
@Override
public ProduceB createProduceB() {
return new ConcreteProduceB2();
}
}
客户端调用
public class Client {
public static void main(String[] args) {
AbstractFactory factory1 = new ConcreteFactory1();
factory1.createProduceA().method();
factory1.createProduceB().method();
AbstractFactory factory2 = new ConcreteFactory2();
factory2.createProduceA().method();
factory2.createProduceB().method();
}
}
扩展(等级结构)
具体产品A3
public class ConcreteProduceA3 implements ProduceA {
@Override
public void method() {
System.out.println("ConcreteProduceA3");
}
}
具体产品B3
public class ConcreteProduceB3 implements ProduceB {
@Override
public void method() {
System.out.println("ConcreteProduceB3");
}
}
具体工厂3
public class ConcreteFactory3 implements AbstractFactory {
@Override
public ProduceA createProduceA() {
return new ConcreteProduceA3();
}
@Override
public ProduceB createProduceB() {
return new ConcreteProduceB3();
}
}
客户端调用
AbstractFactory factory3 = new ConcreteFactory2();
factory3.createProduceA().method();
factory3.createProduceB().method();
开闭原则的倾斜性
如果需要新增一个产品族,需要在抽象工厂里面新增创建该产品的方法,对应的每个具体工厂中都需要实现该方法,新建具体工厂类并实现抽象工厂中的方法。因此,在抽象工厂模式中增加新的产品族很方便,但是增减新的产品等级结构很麻烦,抽象共产模式的这种性质被称为开闭原则的倾斜性。开闭原则要求系统对扩展开放,对修改关闭,通过扩展达到增强某功能的目的,对于设计多个产品族与多个产品等级结构的系统,题功能增强包括两个反方面。
- 增加产品族:对于增加新的产品族,抽象工厂模式很好的支持了开闭原则,只需要增加具体的产品并增加一个具体工厂,对已有的代码无需做任何事情。
- 增加新的产品的等级结构:对于增加新的产品等级结构,需要修改所有的工厂角色。包括抽象工厂,在所有的工厂类中都需要增加新产品的方法,违背了开闭原则。
优/缺点与适用环境
- 优点
- 抽象工厂模式隔离的具体类的生成,使客户端并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易,所有的具体工厂都实现了抽象工厂中定义的公共接口,因此只需要修改具体工厂的实例就可以在某种程度上改变软件系统的行为。
- 当一个产品族中的多个对象设计成一起工作时,他能保证客户端只使用同一个产品族中的对象。
- 增加新的产品族很方便,无需修改已有的系统,符合开闭原则。
- 缺点
- 增加新的产品等级结构麻烦,需要对原有的系统进行较大的修改,甚至需要修改抽象层的代码,这显然会带来较大的不便,违背了开闭原则。
- 适用环境
- 一个系统不应当依赖于产品类实例如何创建、组合和表达的细节,这对于所有类型的工厂模式都是很重要的,用户无需关心对象的创建过程,将对象的创建和使用解耦。
- 系统中有多余一个产品族,而每次只使用其中某一个产品族。可通过配置文件等方式是用户能够动态改变产品族,也可很方便的增加新的产品族。
- 属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。同一个产品族中的产品可以是没有任何关闭的对象,但是他们都有一些共同的约束,如同一组操作系统下的按钮和文本框,按钮和文本框没有任何直接关系,但是它们都是属于某一操作系统的,此时具有一个共同的约束条件,即操作类型的系统。
- 产品等级结构稳定,在设计完成之后不会向系统中增加新的产品登等级结构或者删除已有的等级结构。