定义(Definition)
抽象工厂模式为一个产品家族提供了统一的创建接口。当需要这个产品家族的某一系列的时候,可以从抽象工厂中选出相对的系列来创建一个具体的工厂类别。
动机(Motivation)
在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时,由于需求的变化,
往往存在更多系列对象的创建工作。
结构(Structure)
角色(Roles)
抽象工厂(Abstract Factory):声明一个创建抽象产品对象的接口操作。
具体工厂(Concret Factory):实现创建具体产品对象的操作。
抽象产品(Abstract Product):为一类产品对象声明一个接口。
具体产品(Concrete Product):定义一个将被相应的具体工厂创建的产品对象,实现AbstractProduct接口。
Client仅适用由AbstractFatory和AbstractProduct类声明的接口。
适用情况
1.一个系统要独立于它的产品的创建、组合和表示时。
2.一个系统要多个产品系列中的一个来配置时。
3.需要强调一系列相关的产品对象的设计以便进行联合使用时。
4.提供一个产品类库,而只想显示它们的接口而不是实现时。
举例
还是以华为和OPPO进行举例,他们可以看做两个系列,华为系列,OPPO系列,华为系列又包括华为手机产品,华为平板产品,OPPO系列也同样包括OPPO手机产品,OPPO平板产品。
图中ConcreteFactory1为华为工厂,ConcreteFactory2为OPPO工厂
AbstractProductA为抽象产品手机,AbstractProductB为抽象产品平板电脑
ProductA1是华为手机,ProductA2是OPPO手机
ProductB2是OPPO平板,ProductB1是华为平板
IPhone接口,用来客户端访问,解除与具体手机类访问的耦合,对应于结构图当中的Abstract ProductA
interface IPhone
{
void Start(); //启动
void Off(); //关机
}
HuaWeiPhone具体产品类,对应结构图中的ProductA1
class HuaweiPhone:IPhone
{
public void Start()
{
Console.WriteLine("华为手机开机了");
}
public void Off()
{
Console.WriteLine("华为手机关机了");
}
}
OPPOPhone具体产品类,对应结构图中的ProductA2
class OPPOPhone :IPhone
{
public void Start()
{
Console.WriteLine("OPPO手机开机了");
}
public void Off()
{
Console.WriteLine("OPPO手机关机了");
}
}
ITabletComputer接口,用来客户端访问,解除与具体平板类访问的耦合,对应结构图中的AbstractProductB
interface ITabletComputer
{
void Start();
}
华为具体平板产品类,实现平板接口,对应结构图中的ProductB1
class HuaweiTablet : ITabletComputer
{
public void Start()
{
Console.WriteLine("华为平板电脑启动了");
}
}
OPPO具体平板产品类,实现平板接口,对应结构图中的ProductB2
class OPPOTablet : ITabletComputer
{
public void Start()
{
Console.WriteLine("OPPO平板电脑启动了");
}
}
定义一个抽象工厂接口,对应结构图中的Abstract Factory
interface IFactory
{
IPhone CreatePhone();
ITabletComputer CreateTablet();
}
定义HuaweiFactory具体的工厂类,实现IFactory接口,对应结构图中的ConcreteFactory1
class HuaweiFactory : IFactory
{
public IPhone CreatePhone()
{
return new HuaweiPhone();
}
public ITabletComputer CreateTablet()
{
return new HuaweiTablet();
}
}
定义OPPOFactory具体的工厂类,实现IFactory接口,对应结构图中的ConcreteFactory2
class OPPOFactory : IFactory
{
public IPhone CreatePhone()
{
return new OPPOPhone();
}
public ITabletComputer CreateTablet()
{
return new OPPOTablet();
}
}
客户端代码
IFactory factory = new HuaweiFactory();
IPhone phone = factory.CreatePhone();
phone.Start();
phone.Off();
ITabletComputer tablet = factory.CreateTablet();
tablet.Start();
Console.Read();
运行结果
如果想要创建OPPO系列的手机和平板,只需要改变客户端的代码的下面这行就可以了:
IFactory factory = new HuaweiFactory(); → IFactory factory = new OPPOFactory();
运行结果如下
总结:它适用于系列产品,但是它的缺点是难以支持新种类的产品,因为抽象工厂接口确定了可以被创建的产品集合,所以难以扩展抽象工厂以生产新种类的产品。也就是说,如果现在华为和OPPO又增加了一个新的业务,生产笔记本电脑,那么我们需要在抽象工厂接口中增加,而且华为和OPPO两个具体工厂也要改变,这就违反了开闭原则。
如有问题,欢迎大家指正~~~