策略设计模式

时间:2022-04-10 00:42:17
在开发中,很容易遇到很多个if else的判断情况,比如servlet的这个url干啥,那个url干啥,但是我们可以不写很多个if else
我们完全可以用xml来代替if else的判断,xml更加的直观,且易于维护,tomcat发布web项目就是这样做的,xml代替判断。
或许spring在初始化时,就是把注解和方法一一对应的情况用xml来进行写入,以后直接读取xml来判断执行,或者就是把xml
java bean来代替。

一个类里面的行为有多种不同方式,不同的场景有不同的解决方式。是,我们也可以在方法里面写if else,或者switch case那些条件
判断语句,也可以达到这样的效果,但是这样会很复杂。我们可以把这个类的这个多变的部分提取出来,
用一个接口来直接代替这个可变的部分,然后在使用时,我们想要什么方式或者说是想要怎样处理的方法,
就可以把实现了这个接口的策略类传进来,定义好这个策略,然后使用。
在接下来的例子中,我是把策略接口实现类放在的构造器中,new的时候就定义好策略,但是我们想要更改策略,就得new新对象。
当然我们也可以把策略接口的实现不放在构造器中,可以写一个方法来定义策略,可以随便的更改策略,这时就不用一直的new对象了。

优点:策略类我们可以随便切换;避免了多重的条件判断,如果不同的行为很多,条件判断语句很长,看起来就不舒服;
   扩展性也好,我们想要增加策略,那就写一个策略类,实现接口,重写那个策略方法,就可以直接用了,
   如果是条件判断,我们还得去改那个类的条件判断代码
缺点:策略类会很多

总而言之,就是不同的场景,不同的解决方法,然后我们把这个可变部分抽取出来罢了。

题外话:
    我们项目里面的xml文件,应该在项目初始化就加载,把xml加载成java bean,或者说是用Properties类加载,
  当然我们得用一个单例的类来封装一层,对应一个文件。这样能够尽可能的少占用我们的内存。
    其实像spring之类的框架,都是在初始化的时候,就把很多内在的配置加载成了java bean
  当我们用到的时候,就使用对应的处理。
    比如注解,spring肯定是提前把所有的注解全部加载了的,然后我们用到了哪个,就去找对应的处理方法, 
  这里面也不是写的什么 if else之类的。缺点肯定是改了配置,必须重新初始化,我觉得这也是一种提高框架处理效率的方式,
  把花费的时间放在初始化去做,很多事情在初始化就做完,定死不再更改,不在去重新判断,在项目启动后,
  就不在去处理这些框架的配置了,应该也是提高了效率。
    热部署也不过是有一个java线程,监听文件是否被修改,如果被修改,就reloadrefresh刷新而已。
  不过还是有些框架是还集成了关系型数据库的,在初始化时去动态的取数据库里面的数据来用,
  所以说某些时候可以修改数据库文件来达到动态的修改效果,这也是一种热部署。
 
策略接口
public interface Strategy {

    int change(int a, int b);

}
策略
public class StrategyAvg implements Strategy {

    @Override
    public int change(int a, int b) {
        return (a + b) / 2;
    }
    
}
public class StrategySum implements Strategy {

    @Override
    public int change(int a, int b) {
        return a + b;
    }
    
}
public class TwoNumberChange {

    public String descript;

    public int a;

    public int b;

    public Strategy strategy;

    public TwoNumberChange(String descript, int a, int b, Strategy strategy) {
        this.descript = descript;
        this.a = a;
        this.b = b;
        this.strategy = strategy;
    }

    public void setDescript(String descript) {
        this.descript = descript;
    }

    public void setA(int a) {
        this.a = a;
    }

    public void setB(int b) {
        this.b = b;
    }

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }

    public String getDescript() {
        return descript;
    }

    public int getA() {
        return a;
    }

    public int getB() {
        return b;
    }

    public Strategy getStrategy() {
        return strategy;
    }

    public int getTwoNumChange(){
        return strategy.change(a,b);
    }
}
测试
public class Test {

    public static void main(String [] args){
        TwoNumberChange twoNumberChange1 = new TwoNumberChange("两个数字做运算",2,3,new StrategyAvg());
        System.out.println("(2 + 3) / 2 = " + twoNumberChange1.getTwoNumChange());

        TwoNumberChange twoNumberChange3 = new TwoNumberChange("两个数字做运算",2,3,new StrategySum());
        System.out.println("2 + 3 = " + twoNumberChange3.getTwoNumChange());
    }

}
结果
    (2 + 3) / 2 = 2
    2 + 3 = 5