一、动机
在软件构建过程中,某些使用的算法可能有多种多样且不断变化,如果将这些算法都编码在对象中,将会使得对象异常的复杂,而且有时候支持不适用的算法也是一种负担。
如何在运行时根据需要透明的更改对象的算法?将算法与对象本身解耦,从而避免上述问题?
二、场景
计算税收时,我们可能要支持不同的税收方案,且这样的税收方案容易发生改变且容易扩展。
1、实现方式一
方案一:通过if-else语句或switch语句来判断分支,选择执行不一样的策略
public class Strategy {
enum TaxBase{
/**
* 中国税收
*/
CN_TAX,
/**
* 美国税收
*/
US_TAX
}
public int calculateTax(TaxBase taxBase){
int tax = 0;
switch (taxBase){
case CN_TAX: tax = calculateTax1(); break;
case US_TAX: tax = calculateTax2(); break;
}
return tax;
}
private int calculateTax2() {
return 1;
}
private int calculateTax1() {
return 2;
}
}
缺点: 违背了开闭原则和单一职责原则,当需求发生改变时,至少需要修改switch分支或if-else分支的代码(对原有代码进行了修改)
1、实现方式二(策略模式)
public class Strategy {
/**
* 税收计算接口
*/
interface TaxStrategy{
int calculateTax();
}
/**
* 中国税务计算策略
*/
class CnTaxStrategy implements TaxStrategy{
@Override
public int calculateTax() {
return 1;
}
}
/**
* 美国税务计算策略
*/
class UsTaxStrategy implements TaxStrategy{
@Override
public int calculateTax() {
return 2;
}
}
class SalesOrder{
/**
* 动态绑定,避免switch或if-else
*/
private TaxStrategy taxStrategy;
public SalesOrder(TaxStrategy taxStrategy) {
this.taxStrategy = taxStrategy;
}
public int calculateTax(){
return taxStrategy.calculateTax();
}
}
}
三、概念
定义一系列算法,把他们一个个封装起来,并且使他们可以相互替换,并且使他们相互替换,该模式使得算法可以独立于使用他的客户程序而变化