.Net实战之反射外卖计费

场景

  叫外卖支付,能够有如下优惠:程序员

一、  满30元减12微信

二、  是会员减配送费,好比5元this

三、  优惠券spa

….code

  问题? 如何在不改代码的状况下更灵活的去控制优惠的变化???orm

  有些代码与实际业务可能不符合,旨在体验反射的用处对象

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

--代金券blog

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;
        }
    }
}

--满金额减免get

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群

  

相关文章
相关标签/搜索