在上一篇(工厂方法模式)中我们发现了一个问题,就是一个工坊里面只能生产一个产品?现在问题就来了:突然客户要求,每种产品要分为两种型号,即型号1和型号2。
这时就需要我们对我们的工坊进行改造了,给我们的工坊添加两条生产线,让每个工坊可以同时生产不同型号的产品。
首先是我们的产品,我们要将我们的产品划分为两种不同的型号,分别是型号1和型号2。于是我们把每种产品抽象出来,以产品A为例:
/// <summary>
/// 抽象产品A
/// 集成了工厂类,都是从工厂当中生产的嘛
/// </summary>
public abstract class AbstractProductA : IFactory
{
/// <summary>
/// 名称
/// </summary>
public abstract string Name { get; }
/// <summary>
/// 型号
/// </summary>
public abstract string Model { get; }
/// <summary>
/// 产品内容
/// </summary>
public override void Show()
{
Console.WriteLine($"我是产品{Name},不过我是型号{Model}。");
}
}
然后分别再去实现产品A的两种不同型号。
/// <summary>
/// 产品A的型号1
/// </summary>
public class ProductAModel1 : AbstractProductA
{
public override string Name
{
get
{
return "A";
}
}
public override string Model
{
get
{
return "1";
}
}
}
/// <summary>
/// 产品A的型号1
/// </summary>
public class ProductAModel2 : AbstractProductA
{
public override string Name
{
get
{
return "A";
}
}
public override string Model
{
get
{
return "2";
}
}
}
产品B,产品C依次类推。
好了,现在我们生产的产品已经完成改造了。接下来是对我们的工坊进行进一步的改造,为我们的工坊添加两天生产线,可以同时生产不同型号的两种产品。
/// <summary>
/// 抽象工厂类
/// 用于创建具体的工厂
/// </summary>
public abstract class IWorkshop
{
/// <summary>
/// 型号1的生产线
/// </summary>
/// <returns></returns>
public abstract IFactory CreateModel1();
/// <summary>
/// 型号2的生产线
/// </summary>
/// <returns></returns>
public abstract IFactory CreateModel2();
}
接下来改造A产品的工坊。
/// <summary>
/// 生产A产品的工坊
/// </summary>
public class WorkshopA : IWorkshop
{
public override IFactory CreateModel1()
{
return new ProductAModel1();
}
public override IFactory CreateModel2()
{
return new ProductAModel2();
}
}
依次类推,工坊B和工坊C也做同样的改造。
这时,我们的整个工厂又可以重新开工了,试试改造后的生产线是否正常工作。
static void Main(string[] args)
{
IWorkshop a = new WorkshopA();
IWorkshop b = new WorkshopB();
IWorkshop c = new WorkshopC();
IFactory factory;
Console.WriteLine("型号1的产品:");
factory = a.CreateModel1();
factory.Show();
factory = b.CreateModel1();
factory.Show();
factory = c.CreateModel1();
factory.Show();
Console.WriteLine();
Console.WriteLine("型号2的产品:");
factory = a.CreateModel2();
factory.Show();
factory = b.CreateModel2();
factory.Show();
factory = c.CreateModel2();
factory.Show();
Console.ReadKey(false);
}
运行结果:
可以看出来,相对于工厂模式。我们完成了对一个同类型的产品类的扩展,解决了原来一个工厂只能完成一件事的弊端。其实这就是抽象工厂模式的定义:为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类。
通过上面例子可以看出抽象工厂模式的有点:
· 良好的封装性,每个产品的不同实现不是高层次模块需要关心的。高层次模式小只需要知道如何调用即可(Show方法)。
· 产品族内的约束为非公开状态。
缺点:
虽然抽象工厂模式优点很明显,但是缺点也不容小视。从工厂方法模式改造为抽象工厂模式之后对我们的代码改造巨大,而且每增加一个产品的型号之后,需要修改对应的工坊类,这就违反了“开闭原则”。但这种复杂也是相对的,结合工厂方法模式,可以看出抽象工厂模式难于扩展也是在单独一个产品族内部的,比如要增加一个一个产品型号,要修改的地方非常非常多。但是要增加一个产品却很容易,增加一个工坊即可。
总结一下,抽象工厂模式可以用于有一个共同约束情况下的对象扩展。比如我们要实现一个跨平台的音频播放组件,无论在哪一个平台下,都有播放和暂停的操作。我们只需要建立对应平台的工厂实现即可。那样就可以屏蔽掉对不同操作系统底层的调用,用户只需要关心如何去调用播放和暂停方法即可。
本篇代码下载:点击下载
文章评论