天天看点

java设计模式之策略模式(Strategy)1. 模式的定义2. UML图认识策略模式策略模式的优点策略模式的缺点

1. 模式的定义

假设现在要实现一个简化的报价管理,实现如下的功能: 

1. 对于普通客户或者新客户报全价 

2. 对于老客户报的价格,统一折扣5% 

3. 对于大客户报的价格,统一折扣10% 

对不同的人员报不同的价格

到底该如何实现,才能够让价格类中的计算报价的算法,能很容易地实现可维护,可扩展,又能动态地切换变化呢?

策略模式的定义: 

定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换,使得算法可独立于使用它的客户而变化

2. UML图

java设计模式之策略模式(Strategy)1. 模式的定义2. UML图认识策略模式策略模式的优点策略模式的缺点

Strategy:策略接口,用来约束一系列具体的策略算法,Context使用这个接口来调用具体的策略实现定义的算法

ConcreteStrategy:具体的策略实现,也就是具体的算法实现

Context:上下文,负责和具体的策略类交互,通常会持有一个真正的策略实现

1、

public interface Strategy {

public double calcPrice(double goodsPrice);

}

2、

public class Price {

private Strategy strategy = null;

public Price(Strategy strategy) {

// TODO Auto-generated constructor stub

this.strategy = strategy;

}

public double queryPrice(double goodPrices) {

return this.strategy.calcPrice(goodPrices);

}

}

3、

public class NormalCustomerStrategy implements Strategy {

@Override

public double calcPrice(double goodsPrice) {

// TODO Auto-generated method stub

System.out.println("对于新客户和普通用户没有折扣");

return goodsPrice;

}

}

4、

public class BigerCustomerStrategy implements Strategy {

@Override

public double calcPrice(double goodsPrice) {

// TODO Auto-generated method stub

System.out.println("对于大客户,折扣百分之10%");

return goodsPrice*(1-0.1);

}

}

5、

public class OldCustomerStrategy implements Strategy {

public double calcPrice(double goodsPrice) {

System.out.println("对于老客户,折扣5%");

return goodsPrice*(1-0.05);

}

}

 6、

public class Client {

public static void main(String[] args) {

// TODO Auto-generated method stub

Strategy strategy=new NormalCustomerStrategy();

Price price =new Price(strategy);

double  customerPrice=price.queryPrice(200);

System.out.println("向客户报价==》》"+customerPrice);

strategy=new OldCustomerStrategy();

price=new Price(strategy);

customerPrice=price.queryPrice(200);

System.out.println("向客户报价====》"+customerPrice);

strategy=new BigerCustomerStrategy();

price=new Price(strategy);

customerPrice=price.queryPrice(200);

System.out.println("向客户报价===》"+customerPrice);

}

}

7、输出结果。

对于新客户和普通用户没有折扣

向客户报价==》》200.0

对于老客户,折扣5%

向客户报价====》190.0

对于大客户,折扣百分之10%

向客户报价===》180.0

从上面的示例可以看出,策略模式仅仅封装算法,提供新的算法插入到已有系统中,以及老算法从系统中“退休”的方法,策略模式并不决定在何时使用何种算法。在什么情况下使用什么算法是由客户端决定的。

认识策略模式

  策略模式的重心

  策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。

  算法的平等性

  策略模式一个很大的特点就是各个策略算法的平等性。对于一系列具体的策略算法,大家的地位是完全一样的,正因为这个平等性,才能实现算法之间可以相互替换。所有的策略算法在实现上也是相互独立的,相互之间是没有依赖的。

  所以可以这样描述这一系列策略算法:策略算法是相同行为的不同实现。

  运行时策略的唯一性

  运行期间,策略模式在每一个时刻只能使用一个具体的策略实现对象,虽然可以动态地在不同的策略实现中切换,但是同时只能使用一个。

  公有的行为

  经常见到的是,所有的具体策略类都有一些公有的行为。这时候,就应当把这些公有的行为放到共同的抽象策略角色Strategy类里面。当然这时候抽象策略角色必须要用Java抽象类实现,而不能使用接口。

  这其实也是典型的将代码向继承等级结构的上方集中的标准做法。

java设计模式之策略模式(Strategy)1. 模式的定义2. UML图认识策略模式策略模式的优点策略模式的缺点

策略模式的优点

  (1)策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免代码重复。

  (2)使用策略模式可以避免使用多重条件(if-else)语句。多重条件语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重条件语句里面,比使用继承的办法还要原始和落后。

策略模式的缺点

  (1)客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。

  (2)由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。

继续阅读