策略模式就是定义一组算法,将每个算法都封装起来,并且是他们之间可以互换
通过类图可以知道,策略模式设计到如下三个角色
1.Context封装角色
它也叫上下文角色,其作用就是用来封装高层模块对策略的直接访问,封装可能存在的变化
2.Strategy抽象策略角色
策略的抽象,定义每个算法或策略必须具有的方法和属性
3.ConcreteStrategy 具体策略角色
实现抽象策略中的操作
下面是上述类图的代码实现:
/** * * 抽象策略角色 * */ public abstract class Strategy { // 抽象算法 public abstract void exec(); }
public class ConcreteStragegyA extends Strategy { /** * * @see com.huashao.chapter.chapter18.ch01.Strategy#exec() */ @Override public void exec() { System.out.println("ConcreteStragegyA"); } }
public class ConcreteStragegyB extends Strategy { /** * * @see com.huashao.chapter.chapter18.ch01.Strategy#exec() */ @Override public void exec() { System.out.println("ConcreteStragegyB"); } }
public class ConcreteStragegyC extends Strategy{ /** * * @see com.huashao.chapter.chapter18.ch01.Strategy#exec() */ @Override public void exec() { System.out.println("ConcreteStragegyC"); } }
public class Context { private Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } public void action() { strategy.exec(); } }
记得有位名人曾经说,人只有两件事没有办法逃避,那就是交税和死亡。
应纳个人所得税税额= 应纳税所得额× 适用税率- 速算扣除数
扣除标准3500元/月(2011年9月1日起正式执行)(工资、薪金所得适用)
个税免征额3500元 (工资薪金所得适用)

其实缴纳税额的计算就可以用策略模式实现,每一个等级的计算看做一种策略
例如:某人某月工资减去社保个人缴纳金额和住房公积金个人缴纳金额后为5500 元,个税计算:(5500-3500)*10%-105=95元
类图如下:

代码如下:
/** * 税收计算器 * */ public abstract class TaxCalculator { // 计算税收的方法 protected abstract void calculate(int amount); }
/** * 等级为1的收税计算 * 全月应纳税所得额不超过1500 */ public class Level01 extends TaxCalculator { /** * @param amount * @see com.huashao.chapter.chapter18.c02.TaxCalculator#calculate(int) */ @Override protected void calculate(int amount) { // 为了简单计算不考虑小数 int tax = amount * 3 / 100 - 0; System.out.println("应交税: " + tax); } }
/** * 等级2:全月应纳税额在1500-4500 * */ public class Level02 extends TaxCalculator { /** * @param amount * @see com.huashao.chapter.chapter18.c02.TaxCalculator#calculate(int) */ @Override protected void calculate(int amount) { // 为了简单计算不考虑小数 int tax = amount * 10 / 100 - 105; System.out.println("应交税: " + tax); } }
/** * *等级3:全月应纳税额在4500-9000 */ public class Level03 extends TaxCalculator { /** * @param amount * @see com.huashao.chapter.chapter18.c02.TaxCalculator#calculate(int) */ @Override protected void calculate(int amount) { // 为了简单计算不考虑小数 int tax = amount * 20 / 100 - 555; System.out.println("应交税: " + tax); } }
public class Context { private TaxCalculator taxcal; public Context(TaxCalculator taxcal) { this.taxcal = taxcal; } // 计算税收 public void calculate(int amount) { taxcal.calculate(amount); } }
其实看上面的策略模式,可以看到它有一个缺点就是客户端必须知道所有的策略,能否不需要客户端知道所有策略也能得到想要的答案呢?答案当然是肯定,下面我们利用前面说的工厂模式修改一下,客户端只需要输入一个金额,程序便返回正确的税收值,类图如下:

代码如下:
/** * 税收等级 * */ public class Level { private int amount; private String level; public Level(int amount) { this.amount = amount - 3500; if (this.amount <= 1500) { level = "A"; } else if (this.amount <= 4500) { level = "B"; } else if (this.amount <= 9000) { level = "C"; } } public int getAmount() { return amount; } public String getLevel() { return level; } }
/** * 税收策略工厂 * */ public abstract class TaxFactory { protected abstract TaxCalculator createTaxCal(Level level); }
/** * */ public class TaxCalFactory extends TaxFactory { /** * @param level * @return */ @Override protected TaxCalculator createTaxCal(Level level) { if ("A".equalsIgnoreCase(level.getLevel())) { return new Level01(); } if ("B".equalsIgnoreCase(level.getLevel())) { return new Level02(); } if ("C".equalsIgnoreCase(level.getLevel())) { return new Level03(); } return null; } }
public class Client { public static void main(String[] args) { Level level=new Level(4000); TaxFactory factory=new TaxCalFactory(); TaxCalculator calculator=factory.createTaxCal(level); calculator.calculate(level.getAmount()); } }