面向对象的编程,并不是类越多越好,类的划分是为了封装,分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类。如商场的打一折和打九折,虽然形式上不同,但是抽象出来的算法是一样的。

策略模式:定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不会影响到使用算法的客户。

以超市的收银软件为例:

现金收费方式类(CashPayMentMethod):

namespace CashierTest.Class
{
    abstract class CashPayMentMethod
    {
        public abstract double acceptCashMethod(double money);
    }
}
View Code

正常收费类(CashNormal):继承于现金收费方式类(CashPayMentMethod)

namespace CashierTest.Class
{
    class CashNormal : CashPayMentMethod
    {
        public override double acceptCashMethod(double money)
        {
            return money;
        }
    }
}
View Code

打折收费类(CashDisCountsCashBack

namespace CashierTest.Class
{
    class CashDisCounts : CashPayMentMethod
    {
        private double moneyDiscounts = 1d;
        public CashDisCounts(double moneyDisCounts)
        {
            this.moneyDiscounts = moneyDisCounts;
        }
        public override double acceptCashMethod(double money)
        {
            return moneyDiscounts * money;
        }
    }
}
View Code

返利收费类:(CashBack):继承于现金收费方式类(CashPayMentMethod)

namespace CashierTest.Class
{
    class CashBack : CashPayMentMethod
    {
        //返现
        private double moneyFullCash = 0.0d; //满多少钱
        private double moneyBackCash = 0.0d; //反多少钱
        public CashBack(double moneyFull, double moneyBack)
        {
            this.moneyFullCash = moneyFull;
            this.moneyBackCash = moneyBack;
        }
        public override double acceptCashMethod(double money)
        {
            double result = money;
            double cashBackTotal = 0.0d;
            while (result > moneyFullCash)
            {
                cashBackTotal += moneyBackCash;
                result = result - moneyFullCash;
            }
            return money - cashBackTotal; //返回实际交的金额
        }
    }
}
View Code

现金上下文类(CashContext):配置和维护对现金收费方式类(CashPayMentMethod)对象的引用。策略模式与简单工厂模式相结合

namespace CashierTest.Class
{
    class CashContext
    {
        CashPayMentMethod cpmm;  //付款方式
        /// <summary>
        /// 简单工厂模式和策略模式相结合
      /// </summary>
       /// <param name="type">付款方式</param>
        public CashContext(string type)
        { 
            switch(type)
            {
                case "正常收费":
                    CashNormal cn = new CashNormal();
                    cpmm = cn;
                    break;
                case "满300返100":
                    CashBack cb = new CashBack(300,100);
                    cpmm = cb;
                    break;
                case "打八折":
                    CashDisCounts cdc = new CashDisCounts(0.8);
                    cpmm = cdc;
                    break;
            }
        }

        public double GetResult(double money)
        {
            return cpmm.acceptCashMethod(money);
        }
    }
}
View Code

客户端代码:

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

        double result = 0.0d;

        private void Form1_Load(object sender, EventArgs e)
        {
            cbxCalculation.Items.AddRange(new object[] { "正常收费", "打八折", "满300返100" });
            cbxCalculation.SelectedIndex = 0;
        }

        private void btnSubmit_Click(object sender, EventArgs e)
        {
               //简单工厂和策略模式相结合
            double totalPrice = 0.0d;
              CashContext context = new CashContext(cbxCalculation.SelectedItem.ToString());
              totalPrice = context.GetResult(Convert.ToDouble(txtUnitPrice.Text) * Convert.ToDouble(txtCount.Text));
              result = result + totalPrice;
              lbxList.Items.Add("单价:" + txtUnitPrice.Text + "  数量:" + txtCount.Text + "  计算方式:" + cbxCalculation.SelectedItem + "  总计:" + totalPrice);
              lblTotalResult.Text = result.ToString();

        }


    }
}
View Code

策略模式结束!

 

 

posted on 2013-08-06 00:43  zxd543  阅读(133)  评论(0编辑  收藏  举报