在工厂方法模式中,我们以造电脑为例,但实际上华为联想不仅造电脑,还造手机,如果完全新建一个造手机的工厂,势必会增加很多重复工作。这里用抽象工厂方法会简化很多,你可以想象为造电脑的工厂同时也可以造手机。
目录
1.UML图
ProductA1和ProductB1是一个系列,ProductA2和ProductB2是另一个系列。ConcreteFactory1是创建系列1的工厂方法,ConcreteFactory2是创建系列2的工厂方法。
也就是A代表电脑,B代表手机。
可以看出,在抽象工厂模式的结构图有以下角色:
(1)、抽象产品类角色(AbstractProduct):为抽象工厂中相互依赖的每种产品定义抽象接口对象,也可以这样说,有几种产品,就要声明几个抽象角色,每一个抽象产品角色和一种具体的产品相匹配。
(2)、具体产品类(ConcreteProduct):具体产品类实现了抽象产品类,是针对某个具体产品的实现的类型。
(3)、抽象工厂类角色(Abstract Factory):定义了创建一组相互依赖的产品对象的接口操作,每种操作和每种产品一一对应。
(4)、具体工厂类角色(ConcreteFactory):实现抽象类里面的所有抽象接口操作,可以创建某系列具体的产品,这些具体的产品是“抽象产品类角色”的子类。
2.案例
重复工厂方法模式的代码就不贴了。
首先是增加Iphone以及具体的手机类。
internal interface IPhone
{
public void Call(string name);
public void Receive(string name);
}
internal class HuaWeiPhone : IPhone
{
public void Call(string name)
{
Console.WriteLine("you use HUAWEI phone call >>>>>>>> "+name);
}
public void Receive(string name)
{
Console.WriteLine("you HUAWEI phone get called <<<<<<< " + name);
}
}
internal class LenovePhone : IPhone
{
public void Call(string name)
{
Console.WriteLine("you use Lenove phone call --------> " + name);
}
public void Receive(string name)
{
Console.WriteLine("you Lenove phone get called <------- " + name);
}
}
抽象工厂有点变化:
internal abstract class Factory
{
public abstract IPhone CreatePhone();
public abstract IComputer CreatePc();
}
华为联想工厂多了新的产品线:
internal class HuaWeiFactory:Factory
{
public override IPhone CreatePhone()
{
return new HuaWeiPhone();
}
public override IComputer CreatePc()
{
return new HuaweiComputer();
}
}
internal class LenoveFactory : Factory
{
public override IPhone CreatePhone()
{
return new LenovePhone();
}
public override IComputer CreatePc()
{
return new LenovoComputer();
}
}
最后随便写一个客户端类:
internal class Client
{
private IComputer computer;
private IPhone phone;
public Client(Factory factory)
{
computer = factory.CreatePc();
phone = factory.CreatePhone();
}
public void Buy()
{
computer.Start();
phone.Call("hello world!");
}
}
3.小结
3.1 要点
- 如果没有应对“多系列对象创建”的需求变化,则没有必要使用AbstractFactory模式,这时候使用简单的静态工厂完全可以。也就是你只有一种产品,且没变化,直接用最简单的工厂模式就好。
- “系列对象"指的是这些对象之间有相互依赖、或作用的关系,例如游戏开发场景中“道路”与“房屋”的依赖,“道路”与“地道”的依赖。
- AbstractFactory模式主要在于应对“新系列”的需求变动。其缺点在于难以应对“新对象”的需求变动。
- AbstractFactory模式经常和FactoryMethod模式共同组合来应对“对象创建”的需求变化。比如后面还要生产平板电脑,就需要两者进行修改。
3.2 优缺点
【抽象工厂】模式将系列产品的创建工作延迟到具体工厂的子类中,我们声明工厂类变量的时候是使用的抽象类型,同理,我们使用产品类型也是抽象类型,这样做就尽可能的可以减少客户端代码与具体产品类之间的依赖,从而降低了系统的耦合度。耦合度降低了,对于后期的维护和扩展就更有利,这也就是【抽象工厂】模式的优点所在。可能有人会说在Main方法里面(这里的代码就是客户端的使用方)还是会使用具体的工厂类,对的。这个其实我们通过Net的配置,把这部分移出去,最后把依赖关系放到配置文件中。如果有新的需求我们只需要修改配置文件,根本就不需要修改代码了,让客户代码更稳定。依赖关系肯定会存在,我们要做的就是降低依赖,想完全去除很难,也不现实。
有优点肯定就有缺点,因为每种模式都有他的使用范围,或者说要解决的问题,不能解决的问题就是缺点了,其实也不能叫缺点了。【抽象工厂】模式很难支持增加新产品的变化,这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。
完整代码:DesignPatterReview