面对对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类
策略模式(Strategy): 定义算法家族,分别起来,让他们之间可与相互替换,此模式让算法的变化,不会影响到使用算法的客户,降低算法类和使用算法类之间的耦合
把一个类中经常改变或者将来可能改变的部分提取出来,作为一个接口,然后在类中包含这个对象的实例,这样类的实例在运行时就可以随意调用实现了这个接口的类的行为。
适用情况
许多相关的类仅仅是行为有异。 “策略”提供了一种用多个行为中的一个行为来配置一个类的方法。即一个系统需要动态地在几种算法中选择一种。
当一个应用程序需要实现一种特定的服务或者功能,而且该程序有多种实现方式时使用。
一个类定义了多种行为 , 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。
优缺点
优点
1、可以动态的改变对象的行为
缺点
1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类
2、策略模式将造成产生很多策略类
策略模式UML类图
Strategy为策略父类,Context为环境类,持有对Strategy的引用
例子:商场促销
策略类(抽象):
// 现金收款超类
abstract class CashSuper {
public abstract double Cash(double money);
}
策略具体实现类:
// 正常收费
public class CashNormal extends CashSuper{
@Override
public double Cash(double money) {
return money;
}
}
// 打折收费
public class CashRebate extends CashSuper{
private double rate;
public CashRebate(double rate) {
this.rate = rate;
}
@Override
public double Cash(double money) {
return money*rate;
}
}
// 返现
public class CashReturn extends CashSuper {
// 返现限制
private double upper;
private double returnMoney;
public CashReturn(double upper, double returnMoney) {
this.upper = upper;
this.returnMoney = returnMoney;
}
@Override
public double Cash(double money) {
if (money > upper){
return money-returnMoney;
}else {
return money;
}
}
}
环境类:
//普通环境类
public class Context {
private CashSuper cs;
public Context(CashSuper cashSuper){
cs=cashSuper;
}
public double getResult(double money){
return cs.Cash(money);
}
}
测试:
public class Test {
// 普通环境类 应用
public static void main(String[] args) {
Context context = null;
String s1="满300减100";
String s2="正常收费";
String s3="打八折";
String type = s3;
switch (type){
case "满300减100":
context = new Context(new CashReturn(300,100));
break;
case "正常收费":
context = new Context(new CashNormal());
break;
case "打八折":
context = new Context(new CashRebate(0.8));
break;
default:
System.out.println("输入错误");
}
System.out.println(context.getResult(500));
}
}
把简单工厂模式与策略模式结合
// 策略模式与简单工厂的结合
public class ContextFactory {
private CashSuper cs =null;
public ContextFactory(String type){
switch (type){
case "满300减100":
cs = new CashReturn(300,100);
break;
case "正常收费":
cs = new CashNormal();
break;
case "打八折":
cs = new CashRebate(0.8);
break;
default:
System.out.println("输入错误");
}
}
public double getResult(double money){
return cs.Cash(money);
}
}
对其测试
// 测试策略模式与简单工厂合并
ContextFactory cf = new ContextFactory(type);
System.out.println(cf.getResult(500));
与简单工厂模式的区别
简单工厂模式创建型模式,他的作用是创建对象
策略模式是行为型模式,它的作用是改变对象的行为,使得行为具有多样性
策略模式可以在各种算法(行为)中动态切换,起到改变行为的作用
工厂模式可以做到的事情,策略模式都可以做到。
策略模式可以做到的事情,工厂模式也可以做到,只是会变得麻烦。
工厂模式关心创建实例,然后通过实例调用其方法。 策略模式更关心实例的行为,在Strategy类中对实例的方法进行封装,然后通过Strategy类调用方法