策略模式

策略模式:定义了算法家族,分别封装起来。让他们之间可以相互替换。

从概念上看,所有的算法完成的都是相同的工作,只是实现不同,他可以以相同的方式调用所有的算法。减少了各种算法与使用算法类之间的耦合。

因此,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。


以下代码主要是封装了加减乘除四种算法。
public class Operation {
	public double getResult(double numA, double numB) throws Exception {
		return 0d;
	}
}

class OperationAdd extends Operation {
	public double getResult(double numA, double numB) {
		return numA + numB;
	}
}

class OperationSub extends Operation {
	public double getResult(double numA, double numB) {
		return numA - numB;
	}
}

class OperationMul extends Operation {
	public double getResult(double numA, double numB) {
		return numA * numB;
	}
}

class OperationDiv extends Operation {
	public double getResult(double numA, double numB) throws Exception {
		if (0d == numB) {
			throw new Exception("除数不能为0");
		} else {
			return numA / numB;
		}
	}
}

当定义好程序中的算法家族后。在StrategyContext中定义Operation属性。而后增加方法getResult间接调用算法。从而得到结果。StrategyContext类代码如下:

public class StrategyContext {

	private Operation operation;
	//结合了简单工厂模式
	public StrategyContext(String operator) throws Exception {
		switch (operator) {
		case "+":
			this.operation = new OperationAdd();
			break;
		case "-":
			this.operation = new OperationSub();
			break;
		case "*":
			this.operation = new OperationMul();
			break;
		case "/":
			this.operation = new OperationDiv();
			break;
		default:
			throw new Exception("运算符错误");
		}
	}
	//当然,也可以这个样子
	public StrategyContext(Operation operation) {
		this.operation = operation;
	}
	public double getResult(double numA, double numB) throws Exception {
		return operation.getResult(numA, numB);
	}

}

这样做法后,当客户端代码需要获取某一种类算法时。只需要将operator传入构造中。而后调用StrategyContext的getResult方法,便可得到正确结果。

public static void main(String[] args) throws Exception {
	Scanner sc = new Scanner(System.in);
	try {
		System.out.println("输入第一个数字A");
		double numA = sc.nextDouble();
		System.out.println("输入运算符:+、-、*、/");
		String operator = sc.next();
		System.out.println("输入第二个数字B");
		double numB = sc.nextDouble();
		
		StrategyContext context = new StrategyContext(operator);//策略模式
		double result = context.getResult(numA, numB);
		System.out.println(String.format("结果是:%s", result));
	} catch (Exception e) {
		throw e;
	} finally {
		sc.close();
	}
}

那么策略模式主要解决了什么问题呢?

  1. 减少了多余了判断。试想,当所有的算法情况,全部写在同一个文件中。通过大量的if-else或case来选择执行方式,那么这段程式的复杂度将会非常之高,可维护性也非常差。
  2. 此外,还可以简化单元测试。因为采取策略模式后,每个算法都有一个属于自己的类。可以单独测试。

回想一下上一篇的"简单工厂模式",似乎也是做类似的事情。那么两者的区别在哪呢?我们看一下两者区别:

//简单工厂模式的使用
Operation operation = OperationFactory.getOperation(operator);
double result = operation.getResult(numA, numB);
//策略模式的使用方式
StrategyContext context = new StrategyContext(operator);
double result = context.getResult(numA, numB);

可以看到,简单工厂模式中,需要认识工厂类,以及算法类的基类,通过基类调用getResult方法得到结果。
而策略模式中,只需要知道StrategyContext类,就可以得到结果。
这使得具体的算法与客户端代码分离,甚至连算法类的基类是谁都可以不知道。反正我只需要调用StrategyContext的getResult方法。耦合性更低。

其次,简单工厂模式,是创建型模式。是负责资源分发。
而策略模式则是行为型模式。两者本质是不同的。

注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值