6月更文挑战|设计模式 —— 策略模式

361 阅读2分钟

这是我参与更文挑战的第7天,活动详情查看:更文挑战

策略模式

策略模式的定义是制定一系列算法将一个算法封装起来,可以让它们互相替换,将选择算法方式选择权外移到客户变化上。

策略模式适用场景:

  1. 针对同一问题有不同种处理方式时,仅仅处理方式内部有所不同。
  2. 抽象类有多个子类,并且处理方式上有if-else或是switch-case场景。

普通方案

如下代码ComputerPower是一个计算电源耗电情况统计,由AsusPower和DellPower两种电源类型区分。每种电源耗电情况不同,每种电源都有自己的耗电算法函数通过开机时长计算出耗电量。当调用计算userPower方法,传参用电时长和电源类型计算出最终耗电量。

但以下代码存在问题:

  1. 一旦电源升级耗电算法发生改变就需要改变耗电函数算法,万一涉及到公共耗电函数则容易出错。
  2. 当新增一种电源就需要修改userPower方法对if-else增加新的判断,久而久之当新电源不断增加代码会变得臃肿。
public class ComputerPower{
    private static AsusPower = 1;
    private static DellPower = 2;
    
    private int power(int hours){
        return 10;
    }
    
    private int useAsusPower(int hours){
        if(hours == 1){
            return 2;
        }
        if(hours > 1 && hours < 2){
            return 3;
        }
        if(hours > 2 && hours < 4){
            return 5;
        }
        return power(hours);
    }
    
    private int useDellPower(int hours){
        if(hours == 1){
            return 2;
        }
        if(hours < 2){
            return 4;
        }
        if(hours > 2 && hours < 6){
            return 6;
        }
        return power(hours);
    }  
    
    public static int userPower(int hours,int type){
        if(type == AsusPower){
            return useAsusPower(hours);
        }else if(type = DellPower){
            return useDellPower(hours);
        }
    }
}

优化方案

采用策略模式将多种情况一种处理方式方法userPower接口化,每个电源实现PowerMaker接口的userPower方法函数耗电量算法。当需要知道某种电源的耗电量时,通过类RunPower,设置对应电源实例,然后输入用时就输出该电源的耗电量。

策略模式将每种处理方式相互隔离,互不干涉的同时,对于扩展具有友好型。只需要新增电源类实现接口PowerMaker具体算法,即可作为RunPower入参,并可以计算出新电源类的耗电信息。

public interface PowerMaker{
    int userPower(int hours);
}

public class AsusPower implements PowerMaker{
    @override
    public int userPower(int hours){
        if(hours == 1){
            return 2;
        }
        if(hours > 1 && hours < 2){
            return 3;
        }
        if(hours > 2 && hours < 4){
            return 5;
        }
    }
}

public class DellPower implements PowerMaker{
    @override
    public int userPower(int hours){
        if(hours == 1){
            return 2;
        }
        if(hours < 2){
            return 4;
        }
        if(hours > 2 && hours < 6){
            return 6;
        }
    }
}

public class RunPower{
    PowerMaker powerMaker;
    public setPower(PowerMaker powerMaker){
        this.powerMaker = powerMaker;
    }
    public int userPower(int hours){
        return powerMaker.userPower(hours);
    }  
}
RunPower runPower = new runPower();
runPower.setPower(new DellPower());
runPower.userPower(10);
runPower.setPower(new AsusPower());
runPower.userPower(10);

总结

策略模式将内部处理方式抹去if-else的层次逻辑,将这种判断逻辑抽象化以及拍平处理。

  1. 每种处理途径方式是独立的个体,当算法发生改变只会影响修改一种途径,不会影响其他。
  2. 当新增一种处理方式同样不会破坏内部结构,只需要新增一种处理方式并去使用它即可。 3.策略模式将原有处理方式判断逻辑去除,它只关心实现每种处理方式而不关心客户具体使用哪种方式。将选择权交给客户,让客户去做选择。这也就符合开闭原则,扩展时内部结构不会受到影响。