抽象工厂模式
要创建一组相关或者相互依赖的对象
作用:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
UML类图
抽象基类:
1)AbstractProductA、AbstractProductB:分别代表两种不同类型的产品,由具体的产品派生类对其实现
2)AbstractFactory:抽象工厂类,提供创建两种产品的接口CreateProductA和CreateProductB,由派生的各个具体工厂类对其实现
说明:
AbstractFactory模式关键就是将这一组对象的创建封装到一个用于创建对象的类(ConcreteFactory)中
Abstract Factory模式和Factory最大的差别就是抽象工厂创建的是一系列相关的对象。其创建的实现其实采用的就是Factory模式的方法,对于某种实现,由一个派生出来的抽象工厂实现,对另一种实现,由另一个派生出来的抽象工厂实现。
抽象工厂需要特别注意的地方就是区分不同类型的产品和这些产品的不同实现。显而易见的,如果有n种产品同时有m中不同的实现,那么根据乘法原理可知有n*m个Factory模式的使用
抽象工厂模式与工厂模式的区别
AbstractFactory模式是为创建一组(有多类)相关或依赖的对象提供创建接口,而Factory模式是为一类对象提供创建接口或延迟对象的创建到子类中的实现。并且可以看到,AbstractFactory模式通常都是使用Factory模式实现(ConcreteFactory1)。
工厂方法模式: 一个抽象产品类,可以派生出多个具体产品类。 一个抽象工厂类,可以派生出多个具体工厂类。 每个具体工厂类只能创建一个具体产品类的实例。抽象工厂模式: 多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。 一个抽象工厂类,可以派生出多个具体工厂类。 每个具体工厂类可以创建多个具体产品类的实例。 区别: 工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。 工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
代码实现:
class AbstractProduct
{
protected:
AbstractProduct(){} public:
void SharedThing()
{
//实现产品的共性功能
}
virtual SomeThing() = ; //每个产品都有的功能,具体实现有差异
virtual ~AbstractProduct()=;
}; //两种不同的产品(抽象层) class AbstactProductA:public AbstractProduct
{}; class AbstactProductB:public AbstractProduct
{}; //产品纵向分化,eg对于已经确定的中国人,日本人,又要区分男女了。 class ProductA1:public AbstractProductA
{}; class ProductA2:public AbstractProductA
{}; class ProductB1:public AbstractProductB
{}; class ProductB2:public AbstractProductB
{}; class AbstractFactory
{
protected:
AbstractFactory(){}
public:
virtual AbstractProductA* CreatProductA()=;
virtual AbstractProductB* CreatProductB()=; virtual ~AbstractCreator()=;
}; class ConcreteAbstractFactory1:public AbstractFactory
{
AbstractProductA* CreatProductA()
{
return new ProductA1();
}
AbstractProductB* CreatProductB()
{
return new ProductB1();
}
}; ConcreteAbstractFactory2:public AbstractFactory
{
AbstractProductA* CreatProductA()
{
return new ProductA2();
}
AbstractProductB* CreatProductB()
{
return new ProductB2();
} };
应用
①优点:封装性;产品族内的约束为非公开状态:eg 产品分化的比例(专业内各班级人数平衡)这个问题对于客户是透明的,非公开的
②缺点:产品族扩展困难,每增加一个产品C,就必须在抽象类AbstractCreator中增加对应的方法,同时在每一个具体的工厂方法中加入对应代码,这违反了开闭原则。
使用场景
一个对象族(或一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式。
注意事项
提示:对于抽象工厂模式的缺点
扩展性差说的是产品族扩展困难而不是产品等级。
或者说横向容易,纵向难。
或者说产品末端结点扩展容易(1,2,3),中间难(ABC)
或者说抽象层的扩展难,具象层扩展容易(依赖倒置原则)