設計模式-簡單工廠模式詳解


一、簡單工廠模式的概念

  簡單工廠模式是屬於創建型設計模式,關注於對象的創建。

  我們來考慮一個支付的場景,在點外賣的時候,可以使用選擇支付寶、微信支付、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

       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM