策略模式
定义一组算法家族,分别封装起来。让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的客户。
模型结构图
代码
public class Test {
public static void main(String[] args) {
Context context=new Context(ConcreteStrategyC.class);
context.algorithm();
}
}
public interface Strategy {
public void Algorithm();
}
public class Context {
private Strategy strategy=null;
public Context(Class<?> type){
try {
strategy=(Strategy) type.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void algorithm(){
strategy.Algorithm();
}
}
public class ConcreteStrategyC implements Strategy {
@Override
public void Algorithm() {
System.out.println("ConcreteStrategyC");
}
}
public class ConcreteStrategyB implements Strategy {
@Override
public void Algorithm() {
System.out.println("ConcreteStrategyB");
}
}
public class ConcreteStrategyA implements Strategy{
@Override
public void Algorithm() {
System.out.println("ConcreteStrategyA");
}
}
案例设计
需求:如果有一件商品,由于它在不同的时刻我们会给它分配不通的优惠券,比如无折扣,有折扣,返利等等的福利。
分析与设计:这个时候我们就可以把折扣作为我们的策略,根据不同的时刻来给商品计算折后价格。
代码
public class Test {
public static void main(String[] args) {
CashContent cashContent=new CashContent(CashNormal.class);
BigDecimal acceptCash = cashContent.acceptCash();
System.out.println(acceptCash.longValue());
}
}
public interface CashSuper {
public BigDecimal acceptCash();
}
public class CashReturn implements CashSuper{
@Override
public BigDecimal acceptCash() {
return new BigDecimal(1);
}
}
public class CashRebate implements CashSuper{
@Override
public BigDecimal acceptCash() {
return new BigDecimal(2);
}
}
public class CashNormal implements CashSuper {
@Override
public BigDecimal acceptCash() {
return new BigDecimal(1);
}
}
public class CashContent implements CashSuper {
private CashSuper cashSuper=null;
public CashContent(Class cashSuper) {
try {
this.cashSuper=(CashSuper) cashSuper.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public BigDecimal acceptCash() {
// TODO Auto-generated method stub
return cashSuper.acceptCash();
}
}
public class Test {
public static void main(String[] args) {
CashContent cashContent=new CashContent(CashNormal.class);
BigDecimal acceptCash = cashContent.acceptCash();
System.out.println(acceptCash.longValue());
}
}
总结
1 策略模式为上下文提供了可重用的算法与行为,继承有助于析取出一系列可供重用的算法与行为。简化了单元测试,每一个算法都有自己的类,可以通过自己的接口进行单独测试。
2 swich语句,大量的if else语句,不同的行为堆砌在一个类中时,就很难避免使用条件语句来选择合适的行为。这些个行为封装了一个个独立的策略可以使用这些行为的类来消除条件语句。
3 策略模式是用来封装算法的。但在实践中,我们发现可以用他来封装几乎任何类型的规则。需要在不同的条件下,执行不同的业务规则,而且业务规则相对复杂独立,就可以考虑使用策略模式来进行处理。
4 可以选择使用反射的类类型,来代替条件选择。