java设计模式之策略模式(Strategy)

1. 模式的定义

假设现在要实现一个简化的报价管理,实现如下的功能: 
1. 对于普通客户或者新客户报全价 
2. 对于老客户报的价格,统一折扣5% 
3. 对于大客户报的价格,统一折扣10% 
对不同的人员报不同的价格

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

策略模式的定义: 

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

2. UML图



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

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

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


1、
/**
 * 
 * @author  zlb
 * 策略,定义计算价格报价算法的接口
 *
 */
public interface Strategy {
/**
* 计算应有的报价
* @param goodsPrice
* @return
*/
public double calcPrice(double goodsPrice);

}

2、

/**
 * 价格管理,主要完成计算向客户提供所报价格的功能
 * @author Administrator
 *
 */
public class Price {


/**
* 只有一个具体的策略对象
*/
private Strategy strategy = null;


/**
* 构造方法,传入一个具体的策略对象
* @param strategy
*/
public Price(Strategy strategy) {


// TODO Auto-generated constructor stub
this.strategy = strategy;
}


/**
* 计算对客户的报价。
* @param goodPrices
* @return
*/
public double queryPrice(double goodPrices) {
return this.strategy.calcPrice(goodPrices);
}


}


3、/**
 * 具体算法的实现,为新客户和普通客户计算应有的报价
 * @author Administrator
 *
 */
public class NormalCustomerStrategy implements Strategy {
@Override
public double calcPrice(double goodsPrice) {
// TODO Auto-generated method stub
System.out.println("对于新客户和普通用户没有折扣");
return goodsPrice;
}

}

4、/**
 * 具体算法实现,为大客户计算应有的报价
 * @author Administrator
 *
 */
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、

/**
 * 具体算法实现,为老客户计算应有的价格报价
 * @author Administrator
 *
 */
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抽象类实现,而不能使用接口。

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

 

策略模式的优点

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

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

策略模式的缺点

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

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




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值