65.9K
CodeProject 正在变化。 阅读更多。
Home

创建型模式 - 抽象工厂

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.55/5 (6投票s)

2002年2月21日

3分钟阅读

viewsIcon

90447

downloadIcon

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。

© . All rights reserved.