设计模式-策略模式

策略模式是一种定义一系列算法的方法,这些算法完成的都是相同的工作,只是实现不同。它可以用相同的方法来调用这些算法,减少了算法类和使用它们的类之间的耦合。而且,策略模式会简化单元测试,因为每个算法有自己的类,可以通过自己的接口进行单元测试。

现在我们来开发一个商场收银程序,商场经常会有促销活动,比如打折,比如满减,比如积分等等。这些其实都是一些算法,这些算法完成的都是同样的事情,就是通过给定的原价,来计算出最终的价格。那么我们就可以用策略模式来实现这个程序。

首先我们需要有一个父类,来抽象出这些算法。

public abstract class CashSuper {
	
	public abstract double acceptCash(double money);
}

这个父类定义了一个抽象方法,接收原价,返回最终的价格。

下面我们要定义几种算法,来实现acceptCash方法。

原价算法

public class CashNormal extends CashSuper{

	public double acceptCash(double money){
		return money;
	}
}

打折算法

public class CashRebeat extends CashSuper {
	private double rebate = 1;
	
	public CashRebeat(double rebeat){
		this.rebeat = rebeat;
	}
	
	public double acceptCash(double money){
		return rebeat * money;
	}
}

满减算法

public class CashReturn extends CashSuper {
	private double condition = 0;
	private double moneyReturn = 0;
	
	public CashReturn (double condition,double moneyReturn) {
		this.condition = condition;
		this.moneyReturn = moneyReturn;
	}
	
	public double acceptCash(double money){
		return money - Math.floor(money / condition) * moneyReturn;
	}
}

然后我们需要定义一个上下文类,维护一个对策略对象的引用

public class Context {
	private CashSuper cashSuper;
	
	public Context (CashSuper cashSuper) {
		this.cashSuper = cashSuper;
	}
	
	public double getResult(double money) {
		return cashSuper.acceptCash(money);
	}
}

当我们要用的时候,就可以传给Context不同的对象,来实现不同的策略。
比如

private Context context;

switch(type) {
case "原价":
	context = new Context(new CashNormal());
	break;
case "打八折" :
	context = new Context(new CashRebeat(0.8));
	braek;
}

System.out.println(context.getResult(money));

但这样会将选择算法的任务交给调用方,耦合度很高。我们希望调用方只关心自己的打折方式、原价,最终价格,不需要参与算法的选择。所以我们可以将简单工厂模式与策略模式结合起来。用简单工厂来生产策略。
重写上下文类

public class Context {
	private CashSuper cashSuper;

	public Context (String type) {
		switch(type) {
		case "原价":
			cashSuper = new CashNormal();
			break;
		case "打八折" :
			cashSuper = new CashRebeat(0.8));
			braek;
		}
	}
	
	public double getResult(double money) {
		return cashSuper.acceptCash(money);
	}
}

这个时候调用方就不需要考虑生成什么策略了,只需要将参数传给上下文对象,由上下文对象自动生产出算法对象即可。

private Context context;

context = new Context("打八折")System.out.println(context.getResult(money));

可以看到调用方只和Context对象进行了交互,实现了解耦。如果这里我们使用简单工厂来实现呢?
调用方需要有一个父类的引用,还需要调用简单工厂来生产具体算法类。所以用简单工厂会和2个类进行交互。所以在这个例子中,策略模式减少了耦合。

相关demo可以参考我的gitee仓库
https://gitee.com/akitsuki-kouzou/DesignPatternDemo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值