工厂方法模式
需要记住的最重要的一点是,工厂方法设计模式与简单工厂设计模式并不完全相同。大多数人认为两者是相同的,因此他们可以互换地使用术语工厂和工厂方法,这是不对的。
一、什么是工厂方法设计模式?
根据Gang of Four的定义 “定义一个用于创建对象的接口,但是让子类决定实例化哪个类。工厂方法允许类将其用于子类的实例化推迟”
让我们简化上述定义。当我们需要创建对象(例如 Product 类的实例)而不向客户端公开对象创建逻辑时,就使用工厂方法设计模式。为了实现这一点,在工厂方法设计模式中,我们将创建一个抽象类作为工厂类,它将创建并返回产品的实例,但是它将让子类决定实例化哪个产品类。如图所示:
二、通过实例了解工厂方法设计模式
通过一个小案例来理解工厂方法设计模式。我们将开发一个显示信用卡信息的应用程序。
我们有三张信用卡,分别是易赏钱信用卡(MoneyBack),钛金卡(Titanium)和铂金卡(Platinum),在程序中对应的就是三个产品类,同样,这三张信用卡类实现CreditCard接口,CreditCard接口定义三个方法获取信用卡的一些信息,这些方法需要由三个具体产品类去实现。
根据工厂方法设计模式的定义,我们需要创建一个工厂类也就是抽象类或接口来用于创建对象,里边声明工厂方法,该方法将返回产品类型的对象,具体步骤如下:
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();
}
}
运行程序,即可获得对应的信用卡信息。