3.5 抽象工厂模式
我们继续对影像家电产品的情形进行分析,我们已经可以使用工厂方法比较好的实现了产品的创建,但是在以前的分析中我们并没有考虑产品种类及生产厂家这样的问题。就拿DVD来说TCL可以生产、LG也生产等等很多厂家都生产。DVD是产品种类中的一种,产品种类这个概念在有些书上称为产品族。从另外一个角度来看TCL可以生产DVD、VCD等等很多产品,这些产品在一起就可以构成一个产品结构。当我们考虑了这些问题后,提出了两个概念:产品种类、产品结构。我们在工厂方法中讨论的是一个个单一的产品的创建,如果我们对这个问题进行进一步的研究、拓展,就应该从单一的产品过度到多个产品种类,在工厂方法中我们考虑DVD是一个单一的产品,现在我们认为DVD是一个产品种类,有TCL生产的DVD,有LG生产的DVD,VCD是另一个产品种类,有TCL生产的VCD,有LG生产的VCD。就这个问题我们重新分析,有两个产品种类分别是DVD、VCD,有两个工厂是TCL和LG,它们分别生产DVD和VCD。我们使用下面的类图来表示:
DVD是抽象类它提供统一的接口,LGDVD、TCLDVD是两个具体的类。VCD和DVD类似。有一个抽象的工厂Create,从它派生了两个具体的类TCLCreate、LGCreate。Create中提供了两个抽象方法factoryDVD和factoryVCD它们提供了两个接口,用于创建DVD产品和VCD产品。在TCLCreate、LGCreate中实现这两个方法。这样TCLCreate就可以创建自己的DVD、VCD,同样LGCreate也可以传经自己的产品。
下面是代码结构:
public abstract class Create
{
public abstract DVD factoryDVD();
public abstract VCD factoryVCD();
}
public class LGCreate: Create
{
public override DVD factoryDVD()
{
return new LGDVD();
}
public override VCD factoryVCD()
{
return new LGVCD();
}
}
public class TCLCreate: Create
{
public override DVD factoryDVD()
{
return new TCLDVD();
}
public override VCD factoryVCD()
{
return new TCLVCD();
}
}
public abstract class DVD
{
public abstract string PlayVideo();
}
public class LGDVD: DVD
{
public override string PlayVideo()
{
return "LG的DVD在播放";
}
}
public class TCLDVD: DVD
{
public override string PlayVideo()
{
return "TCL的DVD正在播放";
}
}
public abstract class VCD
{
public abstract string PlayVideo();
}
public class LGVCD: VCD
{
public override string PlayVideo()
{
return "LG的VCD正在播放";
}
}
public class TCLVCD: VCD
{
public override string PlayVideo()
{
return "TCL的VCD正在播放";
}
}
客户端使用抽象工厂代码如下:
private void button1_Click(object sender, System.EventArgs e)
{
Create TCL,LG;
TCL=new TCLCreate();
LG=new LGCreate();
PlayDVD(TCL); //输出“TCL的DVD在播放”
PlayDVD(LG); //输出“LG的DVD在播放”
}
private void PlayDVD(Create create)
{
DVD dvd=create.factoryDVD();
MessageBox.Show(dvd.PlayVideo());
}
下面将抽象工厂模式推广到一般情况,它的类图如下所示:
抽象工厂:提供所有具体工厂的接口,与应用系统的具体商业逻辑无关。基本上为每一个产品种类提供一个创建方法。
具体工厂:具体负责创建产品结构中每个产品。它包含了创建不同产品的商业逻辑。它实现抽象工厂中的接口。
抽象产品:定义产品的共同接口。
具体产品:是客户需要创建的具体对象。
在工厂方法中每个工厂负责创建一个产品,在抽象工厂中每个工厂创建一系列产品。在上面举例中使用TCL、LG这样的实际的工厂,在实际的应用中,往往是我们根据产品抽象了类,它们主要负责一系列产品的创建,将这些负责抽象工厂的类称为具体工厂,从这些具体工厂更进一步进行抽象,抽象出的工厂称为抽象工厂。下面我们看看抽象工厂模式的扩展。
抽象工厂的扩展包括了新增一个产品种类及新增一个工厂。当在现有的抽象产品下添加新的具体产品时我们仅仅需要增加一个新的工厂就可以。比如现在有了Haier(海尔)的DVD及VCD,我们很容易就实现扩展,而且也满足了“开闭原则”。如下图所示:
当我们有了一个新的产品的增加的时候,就不能很好的满足“开闭原则”了,因为我们需要修改每个产出的方法从而是现有的工厂可以创建出新的产品。比如我们增加一个Mp4产品种类。