设计模式入门-策略模式

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

以下是基本实现代码

ContractedBlock.gifExpandedBlockStart.gifStrategy
 1//抽象算法类
 2ExpandedBlockStart.gifContractedBlock.gifabstract class Strategy{
 3    //算法方法
 4    public abstract void AlgorithmInterface();
 5}

 6
 7//具体算法A
 8ExpandedBlockStart.gifContractedBlock.gifclass ConcreteStategyA extends Strategy{
 9    //算法A的实现方法
10ExpandedSubBlockStart.gifContractedSubBlock.gif    public void AlgorithmInterface() {
11        System.out.println("算法A实现方");
12    }

13}

14
15//具体算法B
16ExpandedBlockStart.gifContractedBlock.gifclass ConcreteStategyB extends Strategy{
17    //算法B的实现方法
18ExpandedSubBlockStart.gifContractedSubBlock.gif    public void AlgorithmInterface() {
19        System.out.println("算法B实现方");
20    }

21}

22
23//具体算法C
24ExpandedBlockStart.gifContractedBlock.gifclass ConcreteStategyC extends Strategy{
25    //算法C的实现方法
26ExpandedSubBlockStart.gifContractedSubBlock.gif    public void AlgorithmInterface() {
27        System.out.println("算法C实现方");
28    }

29}

30
31//上下文
32ExpandedBlockStart.gifContractedBlock.gifclass Context{
33    Strategy strategy;
34ExpandedSubBlockStart.gifContractedSubBlock.gif    public Context(Strategy strategy) {
35        this.strategy = strategy;
36    }

37    //上下文接口
38ExpandedSubBlockStart.gifContractedSubBlock.gif    public void ContextInterface() {
39        strategy.AlgorithmInterface();
40    }

41}

42
43//客户端
44class StrategyTest
45ExpandedBlockStart.gifContractedBlock.gif{
46    public static void main(String[] args) 
47ExpandedSubBlockStart.gifContractedSubBlock.gif    {
48        Context context;
49
50        context = new Context(new ConcreteStrategyA());
51        context.ContextInterface();
52
53        context = new Context(new ConcreteStrategyB());
54        context.ContextInterface();
55
56        context = new Context(new ConcreteStrategyC());
57        context.ContextInterface();
58    }

59}

60

 

如果只用策略模式的话~~会让客户端来判断用哪一个算法,这样不好~所以要把简单工厂模式和策略模式结合起来,把具体判断放入工厂里,下面就是代码,是一个商场打折的代码,具体打折等算法的共同点是有共同的方法需要在客户端调用

 


 

抽象父类~好处不说啦~

ContractedBlock.gifExpandedBlockStart.gifCashBase
1ExpandedBlockStart.gifContractedBlock.gifpublic abstract class CashBase {
2
3    public abstract double getResult(double price);
4
5}

 
非打折算法类

ContractedBlock.gifExpandedBlockStart.gifCashNormal
1ExpandedBlockStart.gifContractedBlock.gifpublic class CashNormal extends CashBase {
2
3ExpandedSubBlockStart.gifContractedSubBlock.gif    public double getResult(double price) {
4        return price;
5    }

6}

 
打折算法类

ContractedBlock.gifExpandedBlockStart.gifCashRebate
 1ExpandedBlockStart.gifContractedBlock.gifpublic class CashRebate extends CashBase {
 2
 3    private double rebate;
 4
 5ExpandedSubBlockStart.gifContractedSubBlock.gif    public CashRebate(double rebate) {
 6        this.rebate = rebate;
 7    }

 8
 9ExpandedSubBlockStart.gifContractedSubBlock.gif    public double getResult(double price) {
10        return price * this.rebate;
11    }

12}

 
返还算法类(算法逻辑写的很差了……可以无视)

ContractedBlock.gifExpandedBlockStart.gifCashReturn
 1ExpandedBlockStart.gifContractedBlock.gifpublic class CashReturn extends CashBase {
 2
 3    private double returnPrice;
 4
 5    private double returnBase;
 6
 7ExpandedSubBlockStart.gifContractedSubBlock.gif    public CashReturn(double returnPrice, double returnBase) {
 8        this.returnPrice = returnPrice;
 9        this.returnBase = returnBase;
10    }

11
12ExpandedSubBlockStart.gifContractedSubBlock.gif    public double getResult(double price) {
13        return price - (price - (price % returnPrice)) / returnPrice * returnBase ;
14    }

15}

 
上下文类和工厂类结合,这样可以把具体逻辑判断封装起来

ContractedBlock.gifExpandedBlockStart.gifCashContext
 1ExpandedBlockStart.gifContractedBlock.gifpublic class CashContext {
 2    
 3    private CashBase cb;
 4    
 5ExpandedSubBlockStart.gifContractedSubBlock.gif    public CashContext(String me) {
 6ExpandedSubBlockStart.gifContractedSubBlock.gif        if ("normal".equals(me)){
 7            cb = new CashNormal();
 8ExpandedSubBlockStart.gifContractedSubBlock.gif        }
 else if ("8 rebate".equals(me)){
 9            cb = new CashRebate(0.8d);
10ExpandedSubBlockStart.gifContractedSubBlock.gif        }
 else if ("300 off 100".equals(me)){
11            cb = new CashReturn(300d, 100d);
12        }

13    }

14
15ExpandedSubBlockStart.gifContractedSubBlock.gif    public double getCash(double price) {
16        return cb.getResult(price);
17    }

18}

19

 

 客户端只需要实例化上下文工厂,不用关心细节

ContractedBlock.gifExpandedBlockStart.gifCashTest
 1class CashTest
 2ExpandedBlockStart.gifContractedBlock.gif{
 3    public static void main(String[] args) 
 4ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 5        CashContext cc = new CashContext("300 off 100");
 6        double price = cc.getCash(1000d);
 7        System.out.println("Result:" + price);
 8    }

 9}

10

 

如果需要添加打折算法则新写一个类继承抽象父类,然后修改上下文工厂即可


 

总结:

  • 策略模式是一种定义一系列算法的方法,从概念上来看,所有算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合
  • 策略模式的Strategy类层次为Context定义了一系列可供重用的算法或行为。继承有助于分析出这些算法中的公共功能
  • 策略模式简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试
  • 当不同的行为堆砌在一个类中时,就很难避免使用条件语句来选择合适的行为。将这些行为封装在一个个独立的Strategy类中,可以在使用这些行为的类中消除条件语句
  • 策略模式就是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性
  • 基本的策略模式中,选择使用具体实现的职责由客户端承担,并转给策略模式的Context对象。这样会增加客户端的压力,所以结合简单工厂模式会减轻这种负担

转载于:https://www.cnblogs.com/lostheaven/archive/2009/01/06/1370361.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值