.Net實戰之反射外賣計費


場景

  叫外賣支付,可以有以下優惠:

1、  滿30元減12

2、  是會員減配送費,比如5元

3、  優惠券

….

  問題? 如何在不改代碼的情況下更靈活的去控制優惠的變化???

  有些代碼與實際業務可能不符合,旨在體驗反射的用處

   public interface IDiscount
    {
        /// <summary>
        /// 優惠名稱
        /// </summary>
        string Name { get; }
        
        /// <summary>
        /// 金額
        /// </summary>
        /// <param name="money"></param>
        /// <returns></returns>
        double CalcMoney(double totalMoney);
    }

--代金券

namespace CashLib
{
    /// <summary>
    /// 代金券
    /// </summary>
    public class CashDiscount:IDiscount
    {
        public string Name
        {
            get { return "代金券:兔子糧票2元,可抵扣2元"; }
        }

        public double CalcMoney(double totalMoney)
        {
            return totalMoney - 2;
        }
    }
}

--會員

namespace MembeLib
{
    /// <summary>
    /// 會員
    /// </summary>
    public class MemberDiscount:IDiscount
    { 
        public string Name
        {
            get { return "會員免5元配送費"; }
        }

        public double CalcMoney(double totalMoney)
        {
            return totalMoney - 5;
        }
    }
}

--滿金額減免

namespace MinusLib
{
    /// <summary>
    /// 足價減金額
    /// </summary>
    public class MinusDiscount : IDiscount
    {
        public string Name
        {
            get { return "滿30減12元"; }
        }

        public double CalcMoney(double totalMoney)
        {
            return totalMoney - 12;
        }
    }
}

--讀取優惠策略的程序集,動態創建類的對象並調用類的成員

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        Dictionary<string, object> dict = new Dictionary<string, object>();
        private void Form1_Load(object sender, EventArgs e)
        {
            string dllPath = AppDomain.CurrentDomain.BaseDirectory + "DiscountLib/";
            string[] assFiles = System.IO.Directory.GetFiles(dllPath, "*.dll");
            foreach (var dllItem in assFiles)
            {
                Assembly ass = Assembly.LoadFrom(dllItem);

                foreach (Type type in ass.GetTypes())
                {
                    if (typeof(IDiscount).IsAssignableFrom(type))
                    {
                        object instanceDiscount = ass.CreateInstance(type.FullName);
                        PropertyInfo propDiscountName = type.GetProperty("Name");
                        string discountName = propDiscountName.GetValue(instanceDiscount).ToString();

                        this.listBox1.Items.Add(discountName);
                        dict.Add(discountName, instanceDiscount);

                    }
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            CustomerOrder cusOrder = new CustomerOrder("張三", 35);
            foreach (string item in this.listBox1.SelectedItems)
            {
                cusOrder.AddDiscount(dict[item] as IDiscount);
            }
            cusOrder.UseDiscount();
        }


    }

--存放優惠券程序集

--結果

--無優惠券

--選擇了代金券糧票

--會員+代金券

--全選

 --有新的優惠券,只需將新的dll放在Debug\DiscountLib文件夾中,系統加載時候會自動加載全部優惠

 --去掉或修改某個優惠,只需直接修改相應代碼或刪除某程序集,不影響其他優惠業務。。。。

 --反射結合抽象類或接口,將會很大程度的提高了程序的拓展性

 --時間倉促,寫的不是很細,更多細節以及反射的操作見下篇,保證這輩子永遠都會熟悉使用反射,如有興趣掃描加入程序員工作聊(必須是程序員)的微信討論組或QQ群

--代碼在QQ群

  


免責聲明!

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



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