创建型模式 - 抽象工厂






2.55/5 (6投票s)
2002年2月21日
3分钟阅读

90447

121
抽象工厂设计模式及其在 C# 和 VB .NET 中的示例实现
引言
设计模式使重用成功的设计和架构变得更容易。 将经过验证的技术表达为设计模式,可以使它们更容易被新系统的开发人员访问。
设计模式帮助您选择使系统可重用的设计方案,并避免损害可重用性的方案。
创建型设计模式抽象了实例化过程。 它们有助于使系统独立于其对象的创建、组成和表示方式。 类创建模式使用继承来改变被实例化的类,而对象创建模式将实例化委托给另一个对象。
一个抽象工厂提供了一个接口,用于创建相关对象族,而无需指定它们的具体类
背景
抽象工厂提供了一个接口,用于创建相关对象族,而无需指定它们的具体类。 有时,人们希望构造一套类中的一个类的实例,并在实例化时决定使用哪个类。 为了避免在创建实例的每个地方都重复进行决策,我们需要一种机制来创建相关类的实例,而不必知道将实例化哪个类。
解决方案
创建一个抽象工厂类来回答具体类(通常是子类)的实例。 抽象工厂的客户端不知道结果实例的类。
抽象工厂有两种类型:一个简单的抽象工厂是一个抽象类,定义了工厂方法来回答具体子类的实例。 选择实例化哪个子类完全取决于使用哪个方法,并且客户端未知。
B 第二种形式的抽象工厂是一个抽象类,定义了工厂方法的通用协议。 抽象工厂的具体子类实现此协议以回答相应类集的实例。 请参阅下文示例,其中包含 VB.net 和 C# 实现
适用性
A 需要从产品的实现细节中抽象出来 - 系统应独立于其组成部分的创建、组成和表示方式。 B 需要有多个产品系列 - 系统应配置为多个产品系列之一。 C 需要强制使用必须一起使用的产品系列 - 一系列相关的产品对象旨在一起使用,您需要强制执行此约束。 D 需要隐藏产品实现并仅呈现接口 - 您希望提供一个产品类库,并且您只想公开它们的接口,而不是它们的实现。
Characteristics
A 抽象工厂是一个对象制造器。 B 它通常可以生产多种类型的对象。 C 它生产的每个对象都仅通过该对象的接口(而不是对象的实际具体实现)为创建对象的接收者所知。 D 抽象工厂可以生产的不同类型的对象是相关的——它们来自一个共同的家族。 E 抽象工厂隔离具体类 F 它使交换产品系列变得容易 G 它促进产品之间的一致性 H 它支持添加新种类的产品及其家族。
示例
此处的示例有一个抽象工厂的实现,作为接口 IAVDevice,它具有可以创建音频对象和视频对象的方法。 客户端代码针对 IAVDevice 编写,并获取 IAudio 和 IVideo 接口。 在命令行中传递“cd”会创建一个 cd 对象系列(音频和视频),而“dvd”则创建一个 dvd 对象系列(音频和视频)。 客户端不关心哪个对象(cd 音频视频或 dvd 音频视频),IAVDevice 接口会返回,因为它针对 IAudio 和 IVideo 接口进行编码。
C# 实现
要从控制台运行示例,首先制作可执行文件,然后使用
csc /out:AbstractFactory.exe AbstractFactory.cs //Creates AbstractFactory
AbstractFactory cd //CD Family
AbstractFactory dvd //DVD Family
using System;
public interface IAVDevice
{
IAudio GetAudio();
IVideo GetVideo();
}
public interface IVideo
{
string GetPictureQuality();
}
public interface IAudio
{
string GetSoundQuality();
}
class CCd:IAVDevice
{
public IAudio GetAudio()
{
return new CCdAudio();
}
public IVideo GetVideo()
{
return new CCdVideo();
}
}
class CDvd:IAVDevice
{
public IAudio GetAudio()
{
return new CDvdAudio();
}
public IVideo GetVideo()
{
return new CDvdVideo();
}
}
class CCdAudio:IAudio
{
public string GetSoundQuality()
{
return "CD Audio is better then DVD Audio";
}
}
class CCdVideo:IVideo
{
public string GetPictureQuality()
{
return "CD video quality is not as good as DVD";
}
}
class CDvdAudio:IAudio
{
public string GetSoundQuality()
{
return "DVD Audio is not as good as CD Audio";
}
}
class CDvdVideo:IVideo
{
public string GetPictureQuality()
{
return "DVD video quality is better then CD";
}
}
class CAVMaker
{
public IAVDevice AVMake(string xWhat)
{
switch (xWhat.ToLower())
{
case "cd":
return new CCd();
case "dvd":
return new CDvd();
default:
return new CCd();
}
}
}
public class AbstractFactory
{
static void Main(string[] args)
{
CAVMaker objFactMaker = new CAVMaker();
IAVDevice objFact;
IAudio objAudio;
IVideo objVideo;
string strWhat;
strWhat = args[0];
objFact = objFactMaker.AVMake(strWhat);
objAudio = objFact.GetAudio();
objVideo = objFact.GetVideo();
Console.WriteLine(objAudio.GetSoundQuality());
Console.WriteLine(objVideo.GetPictureQuality());
}
}
VB.NET 实现
要从控制台运行示例,首先制作可执行文件,然后使用
vbc /out:AbstractFactory.exe AbstractFactory.vb 'Creates AbstractFactory
AbstractFactory cd //CD Family
AbstractFactory dvd //DVD Family
Imports System
Public Interface IAVDevice
Function GetAudio() As IAudio
Function GetVideo() As IVideo
End Interface
Public Interface IAudio
Function GetSoundQuality() As String
End Interface
Public Interface IVideo
Function GetPictureQuality() As String
End Interface
Class CCd
Implements IAVDevice
Public Function GetAudio() As IAudio Implements IAVDevice.GetAudio
GetAudio = New CCdAudio()
End Function
Public Function GetVideo() As IVideo Implements IAVDevice.getVideo
GetVideo = New CCdVideo()
End Function
End Class
Class CDvd
Implements IAVDevice
Public Function GetAudio() As IAudio Implements IAVDevice.GetAudio
GetAudio = New CDvdAudio()
End Function
Public Function GetVideo() As IVideo Implements IAVDevice.GetVideo
GetVideo = New CDvdVideo()
End Function
End Class
Class CCdAudio
Implements IAudio
Public Function GetSoundQuality() As _
String Implements IAudio.GetSoundQuality
GetSoundQuality = "CD Audio is better then DVD Audio"
End Function
End Class
Class CCdVideo
Implements IVideo
Public Function GetPictureQuality() As _
String Implements IVideo.GetPictureQuality
GetPictureQuality = "CD video quality is not as good as DVD"
End Function
End Class
Class CDvdAudio
Implements IAudio
Public Function GetSoundQuality() As _
String Implements IAudio.GetSoundQuality
GetSoundQuality = "DVD Audio is not as good as CD Audio"
End Function
End Class
Class CDvdVideo
Implements IVideo
Public Function GetPictureQuality() As _
String Implements IVideo.GetPictureQuality
GetPictureQuality = "DVD video quality is better then CD"
End Function
End Class
Public Class CAVMaker
Public Function AVMake(ByVal xWhat As String) As IAVDevice
Select Case xWhat.ToLower
Case "cd"
AVMake = New CCd()
Case "dvd"
AVMake = New CDvd()
End Select
End Function
End Class
public Class Client
Public Shared Sub Main(ByVal CmdArgs() As String)
Dim objFactMaker As New CAVMaker()
Dim objFact As IAVDevice
Dim objAudio As IAudio
Dim objVideo As IVideo
Dim strWhat as String
strWhat = CmdArgs(0)
objFact = objFactMaker.AVMake(strWhat)
objAudio = objFact.GetAudio
objVideo = objFact.getVideo
Console.WriteLine(objAudio.GetSoundQuality)
Console.WriteLine(objVideo.GetPictureQuality)
End sub
End Class
参考文献
E. Gamma 等人,“设计模式:可重用面向对象软件的要素” ISBN 0-201-63361-2,Addison Wesley,1995。