策略模式与简易工厂模式是非常相似的。最主要的区别是在功能上,简易工厂模式是为了产出对象,而策略模式是针对一族可替换的算法的。
例如商场的打折,有时候打8折,有时候又有满减的活动。在这个场景下,我们更关心的是我们的折后价是多少,涉及到打折算法的问题,而不是在简易工厂模式中的水果对象,因此,在这种关心可替换算法的场景下,使用策略模式是合适的。
策略模式的UML类图如下(PS.图片来自百度百科):
在这附UML类图中,抽象类Strategy派生了3个子类,它们都实现了同样的方法,但是这个方法的操作逻辑不同。Context类中托管了一个Straegy对象,它们是聚合关系(所谓聚合,就是一种较弱的拥有关系),还有一个对外的ContextInterface方法,这个方法就是用来调用AlgorithmInterface的,利用多态来选择到底使用哪个AlgorithmInterface。
还是拿商场打折的例子:可以定义一个抽象类Discount,里面有一个抽象方法getResult(),用于获取打折后的价格。然后由这个Discount类派生出打8折,打5折之类的类,实现getResult()的逻辑。Context类托管一个Discount对象,里面有一个对外的getResult()方法供客户端调用,在Context类的getResult()方法中,调用Discount对象的getResult()方法。
用Java实现的代码如下:
import java.util.*;
abstract class Discount
{
public abstract float getResult(float money);
}
//打五折
class DiscountF extends Discount
{
public float getResult(float money)
{
return money * 0.5f;
}
}
//打八折
class DiscountE extends Discount
{
public float getResult(float money)
{
return money * 0.8f;
}
}
class Context
{
Discount discount;
Context(int type)
{
//5 表示打五折,8 表示打八折
if(type == 5)
this.discount = new DiscountF();
else if(type == 8)
this.discount = new DiscountE();
}
public float getResult(float money)
{
return discount.getResult(money);
}
}
public class Main
{
public static void main(String args[])
{
//打五折为例
Context context = new Context(5);
System.out.println(context.getResult(1000));
}
}
运行结果如下: