不一样的策略模式(设计模式五)

前言

什么是设计模式?说白了就是套路,是经过历代程序员总结出来的。很多时候我们虽然学会了很多套路,但是啥时候使用,使用哪个合适,我想这才是问题的关键。
知道怎么用不知道什么时候用,这时候看下代码风格也行用的上,策略模式是非常容易通过代码风格使用上的。
策略模式,为什么叫策略模式呢?其实策略模式还有一个别名叫做政策(policy)模式,在古代,对不同的国家呢,实行不同的政策,对A呢,采取税务10%,对B国采取税务20%。
这样根据不同国家政策不同呢,在计算机中就是根据不同对象采取不同的方法,就叫做策略模式咯。但是呢,如果直接采用if else 这种行为呢,人们发现过于臃肿,且复用性极差,那么就形成了这样一种模式去缓解这个问题。
策略模式属于对象行为模式,其实不去看概念也很好记,在运行时针对不同对象,去做出相应的行为。至于为什么不分到结构型或者其他型,只是它更符合行为型,一个类的行为或其算法可以在运行时更改,这些分类其实没有绝对的界限,只是有权威人士对其进行了规划。
那么策略模式的风格是什么,查看正文。

开车出发

public enum PolicyBase
{
    US_Policy,
    DE_Policy,
    FR_Policy
}
public class Strategy
{
    PolicyBase policyBase;

    public Strategy(PolicyBase policyBase) {
        this.policyBase = policyBase;
    }
    public double CalculatePolicy() {
        if (policyBase == PolicyBase.US_Policy)
        {
            return 0.9;
        }
        else if (policyBase == PolicyBase.DE_Policy)
        {
            return 0.8;
        }
        else if (policyBase == PolicyBase.FR_Policy)
        {
            return 0.1;
        }
        return 0;
    }
}

根据不同的国家,采取了不同的政策。这样一看好像没有啥问题啊,根据了不同国家制定了不同税法。
但是呢,在开发代码的时间轴上,也就是未来的角度上存在的极大的问题。比如和英国(GB)合作了,我得改吧?然后又和另外一个国家合作了,恐怕又得来一遍。
这时候有人就纳闷了,还想不改代码?代码的确是要改的,但是不能违法了封闭开发原则。


在红色部分呢,是我们需要继续往下添加代码的地方,也就是我们加一个国家就需要把我们写过的任何一个区域改一遍。
我想这就很糟糕了,牵扯太大,对于发布来说就需要测试整个子模块,我想这代价无法让人接受,这时候策略者模式就出现了。

public enum PolicyBase
{
    US_Policy,
    DE_Policy,
    FR_Policy
}
public interface Policy
{
    double Calculate();
}

public class USPolicy : Policy
{
    public double Calculate()
    {
        throw new NotImplementedException();
    }
}

public class DEPolicy : Policy
{
    public double Calculate()
    {
        throw new NotImplementedException();
    }
}

public class FRPolicy : Policy
{
    public double Calculate()
    {
        throw new NotImplementedException();
    }
}

public class StrategyFactory{
    Policy policy;
    public StrategyFactory(PolicyBase policyBase) {
        switch (policyBase)
        {
            case PolicyBase.US_Policy:
                policy = new USPolicy();
                break;
            case PolicyBase.DE_Policy:
                policy = new DEPolicy();
                break;
            case PolicyBase.FR_Policy:
                policy = new FRPolicy();
                break;
        }
    }
    public Policy GetPolicy() {
        return policy;
    }
}

class SalesOrder
{
    private Policy Policy;

    public SalesOrder(StrategyFactory strategyFactory)
    {
        this.Policy = strategyFactory.GetPolicy();
    }

    public double CalculatePolicy()
    {
        double val = Policy.Calculate();
        return val;
    }

};

上述代码中,通过策略者模式把原来的获取各国的税法比例变成了SalesOrder类,而这个类不再改变,也就是说所以依赖于获取各国税法参数的将依赖于一个稳定的类。
这时候很多纳闷了,如果我需要添加一个英国(GB),依然需要在红色部分就行修改啊,修改的地方如下:


修改的地方一样多,且还要多加一个GBPolicy类,这不是白忙活了吗?
首先我们来看下前后依赖关系图:
使用策略模式前:

使用策略模式后:

这样一看,不仅是没有啥好处,还复杂了。
然而这样一想,我们处理的是解决这个税法问题这个业务上,可以肯定的就是使用策略模式后,我下面红框部分稳定了,也就是在二进制上可以复用,但是上面红色部分倒是有问题了,耦合太大。
但是呢,我们知道上面复杂部分其实就是简单工厂模式,问题就回到了如何优化简单工厂模式了,如果能解决上面红框的问题,那么是可行的。
由于篇幅有限,下一篇总结工厂模式到抽象工厂到反射这个演化。
这时候我们看到了,如果遇到了if else 且以后会增加else if,可以用策略模式,去缓解这个问题,增加代码复用性。
但是稳定的if else 呢是不需要的,比如说星期一到星期日,这种就是稳定的了,本来处于稳定的,那么其改变的价值就不是很大。

uml图

后续补上

总结

策略模式的作用,解决使用不稳定 的if...else 所带来的复杂和难以维护。

原文地址:https://www.cnblogs.com/aoximin/p/12090000.html

时间: 2024-10-16 12:30:00

不一样的策略模式(设计模式五)的相关文章

策略模式 -- 设计模式系列文章(一)

概述 在日常开发工作中,适当的使用一些设计模式,可以让代码扩展性更强,能更好地拥抱变化,让代码更加优雅.本文主要介绍设计模式中的策略模式,并附上测试示例 Demo 供大家参考. 定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化. 个人理解 策略模式,针对那些动作因对象而异的情况下,把每一个动作都独立封装起来并实现同一个接口,通过组合的方式赋予对象相对应的动作,从而使得所有的动作都可以相互替换.通过策略模式,可以达到在运

策略模式设计模式(Strategy)摘录

23种子GOF设计模式一般分为三类:创建模式.结构模型.行为模式. 创建模式抽象的实例.一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化托付给还有一个对象.创建型模式有两个不断出现的主旋律.第一.它们都将关于该系统使用哪些详细的类的信息封装起来.第二,它们隐藏了这些类的实例是怎样被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建.谁创建它.它是怎样被创建的.以及何时创建这些方面

策略模式-设计模式

在讲述之前,我们首先看小例子: 现实生活中我们去商场上买东西的时候,卖场经常根据不同的客户来制定不同的报价策略,比如新客户不打折扣,针对老客户打9折,针对VIP打8折…… 现在我们做一个报价管理模块,简要点就是针对不同的客户,提供不同的报价. 假如是有你来做,你会怎么做?在日常的开发中,我们大部分会写出如下的代码片段: public class QuoteManager { public BigDecimal quote(BigDecimal originalPrice,String custo

策略模式--设计模式系列

今天我们写一个鸭子类,首先分析一下鸭子有哪些特征呢? 鸭子:会叫,会游水,会飞,外观 现在有个需求:分两种鸭子,一种是外观是绿头,一种是红头,写下看: class Duck: def quack(self): print('呱呱叫') def swim(self): print('我会游泳') def display(self):pass def fly(self): print('我会飞') class RedDuck(Duck): def display(self): print('我是红头

三分钟理解“策略模式”——设计模式轻松掌握

实际问题: 由于超市隔三差五就要办促销活动,但每次促销活动的方式不一样,所以需要开发一个软件,营业员只要输入原价再选择活动类型后,就能计算出折扣以后的价钱. 普通人的做法: mian(){ String input = readLine(); double price = readLine(); switch (input) case "九五折": price = price * 0.95; break; case "满100返50": if(price>=1

五分钟一个设计模式之策略模式

五分钟一个设计模式,用最简单的方法来描述设计模式. 开发一个小游戏 还是先来看个例子吧. 有一天老板一拍脑袋,想做一个游戏,于是把你找来,告诉你他的想法: 做一个最简单的闯关游戏,每个关卡都有一些小怪兽,而游戏的角色通过打死所有小怪兽来通关 角色可以使用武器,先做三四个简单的武器,有一般的武器,有厉害的武器,每个武器的伤害值不一样 游戏过程中,角色可以更换武器 先做一个角色,以后可能增加新角色,但不同角色之间的区别现在还没想好. 你作为这个新游戏的主程序员,要做的就是使程序的架构足够灵活,能够为

设计模式学习(十五) 策略模式

策略模式对应于解决某一个问题的一个算法族,允许用户从该算法族中任选一个算法解决某一问题,同时可以方便的更换算法或者增加新的算法,并且由客户端决定调用那个算法 本质: -- 分离算法,选择实现 开发中常见的场景: 代码实现: package strategy; public interface Strategy { public double getPrice(double standardPrice); } 策略接口 package strategy; public class NewCusto

PHP设计模式笔记五:策略模式 -- Rango韩老师 http://www.imooc.com/learn/236

策略模式 1.概述:策略模式,将一组特定的行为和算法封装成类,以适应某些特定的上下文环境,这种模式称为策略模式 例如:一个恶电商网站系统,针对男性女性用户要各自跳转到不同的商品类目,并且所有广告位展示不同的广告 传统的是使用条件分支进行判断,代码不灵活 使用策略模式,要先定义一个约束行为的接口,I_UserStrategy 定义两种策略,男性male和女性female策略类,分别实现了I_UserStrategy. MaleUserStrategy.php FemaleUserStrategy.

五、设计模式之策略模式

策略模式就是提供一组固定算法的策略,客户根据自己的需求选择其中一种策略进行执行. 特点: 预先明确的一组固定算法策略 客户需要选择其中一种策略 场景: 网络爬虫,针对不同的网站,预先提供不同的解析算法 网站预先提供多种登录策略,用户可以任选一种登录方式(用户名密码等,微信登录,QQ登录) 订单支付策略,客户任选一种支付方式(支付宝,微信支付,银联卡支付) 实现方式案例:(实现易扩展,屏蔽if_else_if) 代码: 定义登录策略: package com.kancy.pattern.strat