g bottleColor, string capShape)
{
_bottle = BottleFactory.CreateBottle(bottleColor);
_cap = CapFactory.CreateCap(capShape);
Console.WriteLine("准备英雄需要的瓶子和瓶盖。");
_bottle.ShowInfo();
_cap.ShowInfo();
Console.WriteLine("开始往瓶子了灌入隐形药水,然后封上瓶盖。");
}
}
客户端调用
static void Main(string[] args)
{
ProductMaker pm = new ProductMaker();
pm.MakeProduct("red", "round"); // 提供给英雄红瓶子圆盖子的隐形药水
Console.WriteLine();
pm.MakeProduct("blue", "square"); // 提供给英雄蓝瓶子方盖子的隐形药水
Console.ReadLine();
}
这样,我们通过接口进行隔离,解决了不同瓶子,不同盖子创建时,客户端无需关心具体创建过程,只需要告诉工厂需要何种类型的对象即可。但同时会暴露一个很明显的问题就是,我们创建的瓶子和瓶盖2个对象并不是孤立存在的,2个对象之间是有明显的相互关系的,那就是平口尺寸必须和瓶盖尺寸保持一直,否则就会让店老板出现灌装好药水却拧不上盖子的尴尬。此时应该会对上面提到的抽象工厂的定义有进一步的理解,也在这种场景下,是我们必须要引入抽象工厂模式的时候了。
1 抽象工厂模式详解
0、提炼抽象工厂类
根据抽象工厂方法的结构图,我们首先定义个一个抽象工厂类,该抽象工厂定义瓶子和瓶盖2个对象的创建接口。
/// <summary>
/// 抽象工厂类
/// </summary>
public abstract class AbstractFactory
{
/// <summary>
/// 创建瓶子
/// </summary>
/// <returns></returns>
public abstract IBottle CreateBottle();
/// <summary>
/// 创建瓶盖
/// </summary>
/// <returns></returns>
public abstract ICap CreateCap();
}
1、抽象工厂的具体实现
分析产品的组合情况,实际上只存在2种类型的最终产品,红瓶子圆盖子和蓝瓶子方盖子,我们分别定义2个抽象工厂的具体实现类
/// <summary>
/// 红瓶子圆盖子工厂类
/// </summary>
public class RedBottleAndRoundCapFactory : AbstractFactory
{
/// <summary>
/// 创建瓶子
/// </summary>
/// <returns></returns>
public override IBottle CreateBottle()
{
return BottleFactory.CreateBottle("red");
}
/// <summary>
/// 创建瓶盖
/// </summary>
/// <returns></returns>
public override ICap CreateCap()
{
return CapFactory.CreateCap("round");
}
}
/// <summary>
/// 蓝瓶子方盖子工厂类
/// </summary>
public class BlueBottleAndSquareCapFactory : AbstractFactory
{
/// <summary>
/// 创建瓶子
/// </summary>
/// <returns></returns>
public override IBottle CreateBottle()
{
return BottleFactory.CreateBottle("blue");
}
/// <summary>
/// 创建瓶盖
/// </summary>
/// <returns></returns>
public override ICap CreateCap()
{
return CapFactory.CreateCap("square");
}
}
2、最终产品组装类的修改实现
跟原来的实现相比较,最终产品组装类不在从客户端传入瓶子、瓶盖的参数通过对应的工厂方法创建,而是直接传入已经定义好的瓶子瓶盖组装工厂类对象,能够做到瓶子瓶盖必须配套创建。
/// <summary>
/// 创建最终药水对象
/// </summary>
/// <param name="factory">抽象工厂具体对象</param>
public void MakeProduct(AbstractFactory factory)
{
_bottle = factory.CreateBottle();
_cap = factory.CreateCap();
Console.WriteLine("准备英雄需要的瓶子和瓶盖。");
_bottle.ShowInfo();
_cap.ShowInfo();
Console.WriteLine("开始往瓶子了灌入隐形药水,然后封上瓶盖。");
}
3、客户端调用
ProductMaker pm = new ProductMaker();
AbstractFactory factory = new RedBottleAndRoundCapFactory(); // 提供给英雄红瓶子圆盖子的隐形药水
pm.MakeProduct(factory);
Console.WriteLine();
factory = new BlueBottleAndSquareCapFactory(); // 提供给英雄蓝瓶子方盖子的隐形药水
pm.MakeProduct(factory);
Console.ReadLine();
2 总结
通过创建的多个对象之间的关联关系阐述了抽象工厂模式与其他工厂模式的区别以及使用时机。基于上面的示例,我们可以总结出抽象工厂模式的具有以下优点:
0、分离接口和实现
客户端使用抽象工厂方法来创建需要的对象,只需要传入抽象方法的,无需关注内部具体实现逻辑,实现接口与具体实现的分离解耦。
1、易于产品族切换
一个具体抽象工厂的实现其 |