一、簡單工廠模式的概念
簡單工廠模式是屬於創建型設計模式,關注於對象的創建。
我們來考慮一個支付的場景,在點外賣的時候,可以使用選擇支付寶、微信支付、ApplePay等支付方式。
這些支付方式雖然名字不一樣,但是用法和流程基本類似,都包括了驗證賬號的合法性、檢查支付環境的安全性、驗證支付密碼、從賬號里扣款、通知用戶支付結果等功能。
有共性,我們就抽象出一個基類,然后各種支付方式子類繼承它,再實現自己的業務邏輯。
如果我們希望在使用這些支付方式時,不需要知道這些具體支付方式子類的名字,只需要知道支付方式名字,把該名字傳入一個方法即可返回一個相應的對象,此時,就可以使用簡單工廠模式。
二、實現
1、首先定義一個各種支付方式的抽象類,簡單起見,定義了判斷賬號是否正常、支付、通知用戶幾個方法
namespace SimpleFactory { using System; public abstract class AbstractPaymentMethod { /// <summary> /// 判斷用戶的賬號是否正常 /// </summary> /// <param name="accountNumber">賬號</param> /// <returns>賬號是否正常</returns> public abstract bool IsAccountNormal(string accountNumber); /// <summary> /// 通知用戶 /// </summary> /// <param name="message">通知內容</param> public abstract void NoticeUser(string message); /// <summary> /// 支付過程 /// </summary> /// <param name="accountNumber">用戶賬號</param> /// <param name="amount">金額</param> public virtual void Pay(string accountNumber, decimal amount) { if (this.IsAccountNormal(accountNumber)) { Console.WriteLine($"賬號:{accountNumber}已支付{amount}元"); this.NoticeUser($"尊敬的{accountNumber},您已成功支付{amount}元"); } } } }
2、實現支付寶支付、微信支付
using System; namespace SimpleFactory { public class AliPay : AbstractPaymentMethod { public override bool IsAccountNormal(string accountNumber) { return true; } public override void NoticeUser(string message) { Console.WriteLine("支付寶支付"); Console.WriteLine(message); } } }
using System; namespace SimpleFactory { public class WeiXinPay : AbstractPaymentMethod { public override bool IsAccountNormal(string accountNumber) { return true; } public override void NoticeUser(string message) { Console.WriteLine("微信支付"); Console.WriteLine(message); } } }
3、再定義一個工廠,用來創建這兩種支付方式。這里的工廠方法通過判斷一個枚舉值(PaymentMethodEnum ),來確定需要使用的支付方式
namespace SimpleFactory { using System; public class PaymentMethodFactory { public static AbstractPaymentMethod GetPaymentMethod(PaymentMethodEnum paymentMethod) { switch (paymentMethod) { case PaymentMethodEnum.AliPay: return new AliPay(); case PaymentMethodEnum.WeiXinPay: return new WeiXinPay(); default: throw new NotImplementedException(); } } } }
枚舉類
namespace SimpleFactory { public enum PaymentMethodEnum { /// <summary> /// 支付寶 /// </summary> AliPay = 0, /// <summary> /// 微信支付 /// </summary> WeiXinPay = 1 } }
4、模擬客戶端調用一下
namespace SimpleFactory { using System; class Program { static void Main(string[] args) { AbstractPaymentMethod aliPay = PaymentMethodFactory.GetPaymentMethod(PaymentMethodEnum.AliPay); AbstractPaymentMethod weiXinPay = PaymentMethodFactory.GetPaymentMethod(PaymentMethodEnum.WeiXinPay); aliPay.Pay("Vincent", 700M); Console.WriteLine("*********************************"); weiXinPay.Pay("123456", 1000M); Console.ReadKey(); } } }
5、看看結果

三、總結
簡單工廠模式的優點:
- 工廠類含有必要的判斷邏輯,可以決定在什么時候創建哪一個產品類的實例,客戶端可以免除直接創建產品對象的責任,而僅僅“消費”產品;簡單工廠模式通過這種做法實現了對責任的分割,它提供了專門的工廠類用於創建對象。
- 客戶端無須知道所創建的具體產品類的類名,只需要知道具體產品類所對應的參數即可,對於一些復雜的類名,通過簡單工廠模式可以減少使用者的記憶量。
- 通過引入配置文件,可以在不修改任何客戶端代碼的情況下更換和增加新的具體產品類,在一定程度上提高了系統的靈活性。
簡單工廠模式的缺點:
- 由於工廠類集中了所有產品創建邏輯,一旦不能正常工作,整個系統都要受到影響。
- 使用簡單工廠模式將會增加系統中類的個數,在一定程序上增加了系統的復雜度和理解難度。
- 系統擴展困難,一旦添加新產品就不得不修改工廠邏輯,在產品類型較多時,有可能造成工廠邏輯過於復雜,不利於系統的擴展和維護。
- 簡單工廠模式由於使用了靜態工廠方法,造成工廠角色無法形成基於繼承的等級結構。
基於以上的優缺點,簡單工廠模式適用於以下場景:
- 工廠類負責創建的對象比較少:由於創建的對象較少,不會造成工廠方法中的業務邏輯太過復雜。
- 客戶端只知道傳入工廠類的參數,對於如何創建對象不關心:客戶端既不需要關心創建細節,甚至連類名都不需要記住,只需要知道類型所對應的參數。
代碼下載:https://github.com/hzhhhbb/SimpleFactory
四、參考資料
https://design-patterns.readthedocs.io/zh_CN/latest/creational_patterns/simple_factory.html#id2
