设计模式——策略模式

初识

策略模式(Strategy):它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。是一种行为型模式。

理解:策略模式将每种算法进行封装,并让算法继承于抽象超类。在使用算法的环境中针对抽象策略类,而不是针对具体算法,符合开放-封闭原则。

结构图

在这里插入图片描述
角色:

(1)Context(环境类):负责使用算法策略,其中维持了一个抽象策略类的引用实例。

(2)Strategy(抽象策略类):所有策略类的父类,为所支持的策略算法声明了抽象方法。=> 既可以是抽象类也可以是接口

(3)ConcreteStrategy(具体策略类):实现了在抽象策略类中声明的方法。

应用

Background:某公司为某商场做收银软件,商场不定时有促销活动,活动形式又不限。假设现有三种营销方式:
1、原价
2、消费满300返100
3、消费打8折

结构图:

在这里插入图片描述

实现

double total = 0.0d;
private void btnOK_Click(object sender, EventArgs e)
{

    CashContext csuper = new CashContext(cbxType.SelectedItem.ToString());

    double totalPrices = 0d;
    totalPrices = csuper.GetResult(Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text));
    total += totalPrices;

    lbxList.Items.Add("单价:" + txtPrice.Text + "数量:" + txtNum.Text + " " + cbxType.SelectedItem + " 合计" + totalPrices.ToString());

    lblResult.Text = total.ToString();
}

abstract class CashSuper
{
    public abstract double acceptCash(double money);
}

class CashNormal : CashSuper
{
    public override double acceptCash(double money)
    {
        return money;
    }
}

class CashRebate : CashSuper
{
    private double moneyRebate = 1d;

    public CashRebate(string moneyRebate)
    {
        this.moneyRebate = double.Parse(moneyRebate);
    }

    public override double acceptCash(double money)
    {
        return money * moneyRebate;
    }
}

class CashReturn : CashSuper
{
    private double moneyCondition = 0.0d;

    private double moneyReturn = 0.0d;

    public CashReturn(string moneyCondition, string moneyReturn)
    {
        this.moneyCondition = double.Parse(moneyCondition);

        this.moneyReturn = double.Parse(moneyReturn);
    }

    public override double acceptCash(double money)
    {
        double result = money;
        if (money >= moneyCondition)//判断消费金额是否大于满减金额
        {
            result = money - Math.Floor(money / moneyCondition) * moneyReturn;//实际消费=原价-(消费金额/满减金额取整数)*返回金额
        }

        return result;
    }
}

class CashContext
{

    CashSuper cs = null;
    public CashContext(string type)
    {
        switch (type)//根据客户选择的收费方式,进行收费
        {
            case "正常收费":
                CashNormal cs0 = new CashNormal();
                cs = cs0;
                break;
            case "满300返100":
                CashReturn cs1 = new CashReturn("300", "100");
                cs = cs1;
                break;
            case "打8折":
                CashRebate cs2 = new CashRebate("0.8");
                cs = cs2;
                break;
        }
    }

    public double GetResult(double money)
    {
        return cs.acceptCash(money);
    } 
}

优点

(1)提供了对开闭原则的完美支持,用户可以在不修改原有系统的基础上选择具体算法或行为,也可以灵活地增加新的算法或行为。

(2)避免了多重的if-else条件选择语句,利于系统的维护。

(3)提供了一种算法的复用机制,不同的环境类可以方便地复用这些策略类。

缺点

(1)客户端需要知道所有的策略类,并自行决定使用哪一个策略 => 只适用于客户端了解所有策略算法的情况。
(2)将造成系统产生很多的具体策略类,任何细小的变化都将导致系统要增加一个具体策略类 => 类的个数也许会超出预期。
(3)无法在客户端同时使用多个策略类 => 客户端每次只能使用一个策略类。

应用场景

(1)如果一个系统要动态地在几种算法之间选择其中一种 => 那就快用策略模式吧骚年!
(2)如果有难以维护的多重if-else条件选择语句是为了实现对象的行为 => 那就快用策略模式吧骚年!
(3)不希望客户知道复杂的与算法有关的数据结构,可以将其封装到策略中 => 提高算法的保密性和安全性!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 23
    评论
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值