工厂方法模式

需要记住的最重要的一点是,工厂方法设计模式与简单工厂设计模式并不完全相同。大多数人认为两者是相同的,因此他们可以互换地使用术语工厂和工厂方法,这是不对的。

一、什么是工厂方法设计模式?

根据Gang of Four的定义 “定义一个用于创建对象的接口,但是让子类决定实例化哪个类。工厂方法允许类将其用于子类的实例化推迟”

让我们简化上述定义。当我们需要创建对象(例如 Product 类的实例)而不向客户端公开对象创建逻辑时,就使用工厂方法设计模式。为了实现这一点,在工厂方法设计模式中,我们将创建一个抽象类作为工厂类,它将创建并返回产品的实例,但是它将让子类决定实例化哪个产品类。如图所示:
img

图1 工厂方法类图

二、通过实例了解工厂方法设计模式

通过一个小案例来理解工厂方法设计模式。我们将开发一个显示信用卡信息的应用程序。

我们有三张信用卡,分别是易赏钱信用卡(MoneyBack),钛金卡(Titanium)和铂金卡(Platinum),在程序中对应的就是三个产品类,同样,这三张信用卡类实现CreditCard接口,CreditCard接口定义三个方法获取信用卡的一些信息,这些方法需要由三个具体产品类去实现。
img

图2 产品接口及实现类

根据工厂方法设计模式的定义,我们需要创建一个工厂类也就是抽象类或接口来用于创建对象,里边声明工厂方法,该方法将返回产品类型的对象,具体步骤如下:

Step1:创建产品接口
创建一个名为CreditCard.cs的类文件,它将提供应该由具体产品类实现的方法定义。代码如下:

public interface CreditCard
{
    string GetCardType();

    int GetCreditLimit();

    int GetAnnualCharge();
}

Step2:创建具体产品类
创建三个具体产品类,也就是三个信用卡类,并实现接口中定义的方法:

public class Platinum : CreditCard
{
    public string GetCardType() => "Platinum Plus";
    public int GetCreditLimit() => 35000;
    public int GetAnnualCharge() => 2000;
}
public class Titanium : CreditCard
{
    public string GetCardType() => "Titanium Edge";
    public int GetCreditLimit() => 25000;
    public int GetAnnualCharge() => 1500;
}
public class MoneyBack : CreditCard
{
    public string GetCardType() => "MoneyBack";
    public int GetCreditLimit() => 15000;
    public int GetAnnualCharge() => 500;
}

Step3:创建工厂类
工厂类中定义工厂方法,用于创建产品对象,该方法需要由具体子类实现:

public abstract class CreditCardFactory
{
    protected abstract CreditCard MakeProduct();

    public CreditCard CreateProduct()
    {
        return this.MakeProduct();
    }
}

抽象类中定义一个抽象方法MakeProduct()和一个具体方法 CreateProduct()。CreateProduct()方法在内部调用子类的 MakeProduct()方法,该方法将创建产品实例并返回该实例。
Step4:创建具体产品工厂类
具体创建者对象重写工厂方法以返回具体产品的实例。因为我们有三种类型的信用卡,所以我们将创建三个类,它们将实现抽象的 CreditCardFactory类:

public class MoneyBackFactory : CreditCardFactory
{
    protected override CreditCard MakeProduct()=> new MoneyBack();
}
public class PlatinumFactory : CreditCardFactory
{
    protected override CreditCard MakeProduct()=> new Platinum();
}
public class TitaniumFactory : CreditCardFactory
{
    protected override CreditCard MakeProduct() => new Titanium();
}

就是这样。我们已经完成了实现。让我们将Gang of Four定义与我们的示例进行比较。

根据Gang of Four定义,我们需要定义一个接口或抽象类来创建一个对象。在我们的示例中,它是一个抽象类,即 CreditCardFactory 类。定义的第二部分说明让子类决定实例化哪个类。在我们的示例中,子类是 PlatinumFactory、 MoneyBackFactory 和 TitaniumFactory。因此,这些子类将决定实例化哪个类,例如,MoneyBack、 Titium 和 Platinum。
Step5:客户端调用
如果希望创建 Platinum CreditCard 的实例,那么调用 PlatinumFactory 实例的 CreateProduct 方法,类似地,如果希望创建 Titium CreditCard 的实例,那么调用 TitaniumFactory 实例的 CreateProduct 方法。如下:

class Program
{
    static void Main(string[] args)
    {
        CreditCard creditCard = new PlatinumFactory().CreateProduct();
        if (creditCard != null)
        {
            Console.WriteLine("Card Type : " + creditCard.GetCardType());
            Console.WriteLine("Credit Limit : " + creditCard.GetCreditLimit());
            Console.WriteLine("Annual Charge :" + creditCard.GetAnnualCharge());
        }
        Console.WriteLine("--------------");
        creditCard = new MoneyBackFactory().CreateProduct();
        if (creditCard != null)
        {
            Console.WriteLine("Card Type : " + creditCard.GetCardType());
            Console.WriteLine("Credit Limit : " + creditCard.GetCreditLimit());
            Console.WriteLine("Annual Charge :" + creditCard.GetAnnualCharge());
        }
        Console.ReadKey();
    }
}

运行程序,即可获得对应的信用卡信息。

posted @ 2023-01-25 16:04  初晨~  阅读(78)  评论(0编辑  收藏  举报