设计模式之策略模式

栏目: 后端 · 发布时间: 5年前

内容简介:以前完整的看过《大话设计模式》,虽然完整看过,也做过笔记,但现在依然很多已经很模糊。这段时间趁着离职,有时间,打算重新过一遍,定义(维基百科):策略模式作爲一種軟件設計模式,指對象有某個行爲,但是在不同的場景中,該行爲有不同的實現算法。比如每個人都要“交個人所得稅”,但是“在美國交個人所得稅”和“在中國交個人所得稅”就有不同的算稅方法。策略模式,从模式名称中我们就可以窥探一二。无非就是一个动作可以有不同的策略,有不同的计算方法,我们将计算方法进行封装。如上的例子,美国税务计算、中国的税务计算采用了不同的计算

以前完整的看过《大话设计模式》,虽然完整看过,也做过笔记,但现在依然很多已经很模糊。这段时间趁着离职,有时间,打算重新过一遍, 该篇将介绍策略模式。

一、定义

定义(维基百科):策略模式作爲一種軟件設計模式,指對象有某個行爲,但是在不同的場景中,該行爲有不同的實現算法。比如每個人都要“交個人所得稅”,但是“在美國交個人所得稅”和“在中國交個人所得稅”就有不同的算稅方法。

策略模式,从模式名称中我们就可以窥探一二。无非就是一个动作可以有不同的策略,有不同的计算方法,我们将计算方法进行封装。如上的例子,美国税务计算、中国的税务计算采用了不同的计算方式(不同策略)。还有一个《大话设计模式》中的例子也很好的说明该设置模式,商场折扣,上次可能是满减,这次可能是直接打折,这就是两种不同的策略,那么我们在代码里该怎样设计,才会更清晰抽象这个问题呢?接下来我们就来看看策略模式是怎么抽象该类型的问题的。

二、策略模式UML图

我们看看策略模式是有怎样设计结构的。图片来源于维基百科。可以看到,策略模式定义了一个策略的接口Stragegy,该接口定义了一个方法,即为该策略的操作方法。再实现不同的策略类ConcreteStrategyA、ConcreteStrategyB,继承自策略接口。接着在上下文类Context类持有策略的引用,调用策略。

设计模式之策略模式

三、以商场打折为例子,我们来实现先策略模式。

1、先定义策略接口

package com.design.strategy;

/** * 商场打折接口 */
public interface IShopDiscountStrategy {    
    public int discount(int count);
}复制代码

2、再定义具体的策略

package com.design.strategy;
/** * 满减计算策略 */
public class DiscountFull implements IShopDiscountStrategy 
{    
    //满的金额    
    private int fullCount;    
    //减的金额    
    private int disCash;    
    public DiscountFull(int fullCount,int disCash){         
        this.fullCount = fullCount;        
        this.disCash = disCash;    
    }    
    @Override    
    public int discount(int count) {            
        if (count >= fullCount){            
            return count -disCash;        
        }        
        return count;    
    }
}复制代码
package com.design.strategy;
/** * 打折策略,打7折 */
public class DiscountPercent implements IShopDiscountStrategy 
{    
    //折扣率    
    private float disPer;    
    public DiscountPercent(float disPer){        
        this.disPer = disPer;    
    }    
    @Override    
    public int discount(int count) {        
        return (int) (count * disPer);    
    }
}复制代码

3、再定义上下文类,持有具体的策略引用。

package com.design.strategy;
public class DiscountContext {    
    private IShopDiscountStrategy iShopDiscountStrategy;    
    public DiscountContext(IShopDiscountStrategy iShopDiscountStrategy) {        
        this.iShopDiscountStrategy = iShopDiscountStrategy;    
    }    
    public int discount(int count){        
        return iShopDiscountStrategy.discount(count);    
    }
}复制代码

到此,策略模式编写的打折场景已经编写完毕,在来看看怎么调用

package com.design.strategy;public class StrategyTestMain {
    public static void main(String[] args) {        
        //使用满减策略计算实收总额        
        DiscountContext discountContext = new DiscountContext(new DiscountFull(200, 100));
        System.out.println(discountContext.discount(200));        
        //使用折扣策略计算实收总额        
        DiscountContext discountContext1 = new DiscountContext(new DiscountPercent(0.7f)); 
        System.out.println(discountContext1.discount(200));    
    }
}复制代码

四、优缺点

优点

1、简化单元测试

从例子我们就可以看出来每个策略都有单独的类来实现,我们可以当度对策略进行测试。

2、扩展性好

我们要定义新的策略,只需要编写一个新的策略,并对新策略进行测试即可,不修改原来已经存在策略的代码。

3、避免使用多重条件转移语句

策略模式中使用的策略是有客户端选择的,策略相关的类不需要通过多重条件去选择策略。

缺点

1、客户端需自行决定使用的策略

客户端必须知道所有的策略类,并自行决定使用哪一个策略类。

2、定义的类比较多

每个策略都得定义一个类来实现。

结语

策略模式暂时总结到这里。看起来策略模式还是比较简单的,就是将不同的策略进行封装。实际适用于一个操作有不同的策略的应用场景中。如JDK中创建线程池,线程池任务满时,对提交的任务做处理就使用了策略模式。可以在创建线程池时,传入相应的处理策略。如下,最后一个参数传入一个处理策略。策略接口为RejectedExecutionHandler,具体的实现有:DiscardOldestPolicy,AbortPolicy....

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,
        long keepAliveTime,TimeUnit unit,
        BlockingQueue<Runnable> workQueue,
        RejectedExecutionHandler handler)复制代码

以上所述就是小编给大家介绍的《设计模式之策略模式》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

High Performance Python

High Performance Python

Micha Gorelick、Ian Ozsvald / O'Reilly Media / 2014-9-10 / USD 39.99

If you're an experienced Python programmer, High Performance Python will guide you through the various routes of code optimization. You'll learn how to use smarter algorithms and leverage peripheral t......一起来看看 《High Performance Python》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

SHA 加密
SHA 加密

SHA 加密工具

html转js在线工具
html转js在线工具

html转js在线工具