5_策略模式

写在前面:设计模式不是干掉变化,而是让变化集中到一个区域,方便开发。

 

策略模式最大价值就是干掉了选择,特别是switch,通过这种模式,可以干掉在代码在switch中的强耦合关系。

按照惯例,还是来个生活写照:有一个国际的税务组织,需要和各国的税务规则打交道,每个国家都有自己的税务体系,需要根据实际的业务使用对应的税法规则。

用代码来模拟这个业务,一种简单的实现如下(把对应的国家信息传过去,根据这些信息来判断调用那个国家的税法规则):

 

enum COUNTRY {
	CN_Tax,
	FR_Tax,
	US_Tax
}

public class StrategyTest {
    public static void main(String[] args) {
		TaxStrategy strategy = new TaxStrategy();
		CalculateTax calculateTax = new CalculateTax();
		strategy.setCalculateTax(calculateTax);
		strategy.business(COUNTRY.CN_Tax);//中国税法
	}
}

class TaxStrategy{
	
	private CalculateTax calculateTax;
	
	public void setCalculateTax(CalculateTax calculateTax) {
		this.calculateTax = calculateTax;
	}
	//具体的业务
	public void business(COUNTRY country) {
		calculateTax.calculate(country);
	}
}

class CalculateTax {
	//根据具体的国家计算税收
	public void calculate(COUNTRY country) {
		switch (country) {
		case CN_Tax:
			System.out.println("中国税法");
			break;
        case FR_Tax:
        	System.out.println("法国税法");
			break;		
        case US_Tax:
        	System.out.println("美国税法");
	        break;

		default:
			break;
		}
	}
	
}

代码本身很简单,这里来分析一下这种实现在设计上的问题,在上面的模拟中有两处变化,第一处是main函数中调用需要传递的国家信息来选择税法,第二处是根据国家判断对应的税法规则。第一处我们没法动,但是第二处可以优化。试想一下当需要增加一个国家时,就必须增加switch里面的case项,但是我们不希望改变里面的代码。那就可以采用派生的方式来解决。

 

public class StrategyTest {
    public static void main(String[] args) {
    	TaxStrategy strategy = new TaxStrategy();
    	ICalculateTax calculateTax = new CNTax();
    	strategy.setCalculateTax(calculateTax);
    	strategy.business();
	}
}

class TaxStrategy {
	private ICalculateTax calculateTax;
	
	public void setCalculateTax(ICalculateTax calculateTax) {
		this.calculateTax = calculateTax;
	}
	//具体的业务
	public void business() {
		calculateTax.calculate();
	}
}

//税收规则抽象接口
interface ICalculateTax {
	void calculate();
}

//中国税收规则抽象接口实现
class CNTax implements ICalculateTax {

	public void calculate() {
		System.out.println("中国税法");
	}
}
//美国税收规则抽象接口实现
class USTax implements ICalculateTax {

	public void calculate() {
		System.out.println("美国税法");
	}
}
//法国税收规则抽象接口实现
class FRTax implements ICalculateTax {

	public void calculate() {
		System.out.println("法国税法");
	}
}

通过派生的方式,来实现晚绑定,把第二处的变化都“赶”到ICalculateTax的实现类里面了,而且删除和增加都很方便,这也是策略模式的精华所在。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值