策略模式
首先来看一下定义
策略模式(Strategy):定义一组算法,将每个算法都封装起来,并且使他们之间可以互换
策略模式主要有三点组成
- 抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
- 具体策略角色:包装了相关的算法和行为。
- 环境角色:持有一个策略类的引用,最终给客户端调用。
举个栗子:
我中午想吃好吃的,但可以吃的东西有很多种:烤鸭、龙虾、帝王蟹,但是不管吃啥,都是吃,所有就有了抽象策略角色
interface Dine{
void eat();
}
//下面这些是具体吃啥,也就是具体策略角色
class RoastDuck implements Dine{
public void eat(){System.out.println("烤鸭真好吃");}
}
class Lobster implements Dine{
public void eat(){System.out.println("龙虾真好吃");}
}
class KingCrab implements Dine{
public void eat(){System.out.println("螃蟹真好吃");}
}
//最后是环境角色
class EatContext{
Dine dine=null;
//通过构造方法传入具体的策略类
public EatContext(Dine dine){
this.dine=dine;
}
//实现吃饭
public void start(){
dine.eat();
}
}
//客户端代码
public class Client{
public static void main(String[] args){
//中午吃龙虾
EatContext eat=new EatContext (new Lobster());
eat.start();
}
}
策略模式的优点还是很明显的
- 算法可以自由的切换,通过实现抽象策略,通过封装角色对其封装,保证对外提供“可自由切换”的策略。
- 避免使用多重条件判断,如果有多重策略,那么每个策略只需实现自己的方法,至于采用何种策略,可以通过其他模块决定。
- 扩展性良好,可以在现有的系统中任意的加入新的策略,只需继承策略接口
同样的缺点也有
- 策略类数量增多,每个策略都是一个类,复用的可能性很小,类数量增多
- 所有的策略都需要对外暴露,上层模块必须知道有哪些策略,然后才能知道采用哪种策略,可以通过使用工厂方法模式、代理模式和享元模式修正。
还记得昨天工厂模式的问题吗?今天刚好结合策略模式互补。
这里我直接继续工厂模式博客的代码(耦合度高了,不过这个正是我想的,因为我懒啊!嘿嘿!),我把工厂类和产品直接看成了策略就不再进行更改了(网络上的都是把简单工厂和策略模式结合,我这里是借用这个思想弄出来)
//首先增加策略类
class Strategy{
private Factory factory=null;
private Operation operation=null;
//直接把客户端的判断逻辑拿过来
public Strategy(String symbol){
switch (symbol) {
case "+":
factory=new AddFactory();
break;
case "-":
factory=new SubFactory();
break;
case "*":
factory=new MulFactory();
break;
case "/":
factory=new DivFactory();
break;
}
operation=factory.creatOperation();
}
public double sendResult(double numA,double numB){
return operation.getResult(numA,numB);
}
}
//客户端
public class Calc{
public static void main(String[] args){
Scanner sca=new Scanner(System.in);
System.out.println("请输入第一个数字");
String numA=sca.nextLine();
System.out.println("请输入算数符号");
String symbol=sca.nextLine();
System.out.println("请输入第二个数字");
String numB=sca.nextLine();
double amount=0.0;
double first=Double.valueOf(numA);
double second=Double.valueOf(numB);
Strategy strategy=new Strategy(symbol);
amount=strategy.sendResult(first,second);
System.out.println(amount);
}
}
好了目前的就先写到这里了,套用大话设计思想中的一句原话
任何的需求变更都是需要成本的,但成本高低还是有差异的
高手和菜鸟的区别就是,高手可以花同样的代价获得更高的收益或者做同样的事花最小的代价
努力向高手看齐。