策略模式及优化

(本文参考了《设计模式之禅》一书)

何时应该使用策略模式?

当我们的程序中某些算法需要自由切换时非常适合使用策略模式。

比如我们写一个计算机程序,里面必然有加减乘除等等算法,并且这些算法还应该根据客户点击什么运算符号来自由切换。我们就以加 减算法的实现为例说明如何使用策略模式来优化代码,以及如何优化策略模式。

我们实现计算机的 加 减 算法,最简单的写法应该是这样

算法类

public class Calculator {
    public final static String ADD = "+";
    public final static String SUB = "-";

    //算法加
    private static int add(int a,int b){
        return a + b;
    }

    //算法减
    private static int sub(int a,int b){
        return a - b;
    }

    //计算
    public static int exe(int a,int b,String exeMethod){
        switch (exeMethod) {
        case ADD:
            return add(a,b);
        case SUB:
            return sub(a,b);
        default:
            return 0;
        }
    }
}

场景类

public class Context {

    public static void main(String[] args) {
        int a = Calculator.exe(3, 4, Calculator.ADD);  //加法运算
        int b = Calculator.exe(3, 4, Calculator.SUB);  //减法运算
        System.out.println(a+" "+b);
    }
}

现在我们引入策略模式

先定义一个抽象接口

public interface Strategy {
    int exe(int a,int b);
}

再实现加和减算法

//加法
public class CalculatorAdd implements Strategy{

    @Override
    public int exe(int a, int b) {
        return a + b;
    }

}

//减法
public class CalculatorSub implements Strategy{

    @Override
    public int exe(int a, int b) {
        return a - b;
    }

}

可以看到,我们每个算法都继承了Strategy接口,并且实现的exe()方法。

最后看场景类

public class Context {

    public static void main(String[] args) {

        int a = exe(3,4,new CalculatorAdd());
        int b = exe(3,4,new CalculatorSub());
        System.out.println(a+" "+b);
    }

    public static int exe(int a,int b,Strategy strategy){
        return strategy.exe(a, b);
    }
}

场景类中的 exe()方法通过传入不同的 Straregy 实现类来完成算法的切换。

我们可以看到,使用了策略模式之后,代码量以及类的数目都比之前多了一些,那么为什么还要使用策略模式呢?策略模式的一个好处是规范了我们的代码。比如我们想要新增一个乘法,那么必须要实现 Strategy 接口,然后实现 exe()方法来编写实际的算法。

虽说如此,但策略模式的问题仍然不少,比如类的数量过多。还有一个致命的缺点就是所有的策略类都必须对外暴露,不然我们就没办法知道有哪些策略类可用,但是这样又违背了迪米特法则,故我们还需要对策略模式进行一些优化,可以将策略模式和别的模式结合使用,来解决上述问题。

我们可以使用策略枚举方法,算法枚举类实现如下:

public enum Calculator {
    ADD{
        @Override
        public int exe(int a, int b) {
            return a + b;
        }

    },
    SUB{
        @Override
        public int exe(int a, int b) {
            return a - b;
        }

    };

    public abstract int exe(int a, int b);
}

该枚举类中有一个exe()抽象方法,枚举类中的每个成员都要实现该方法来实现具体的算法。

然后在场景类中我们就可以这样使用

public class Context {

    public static void main(String[] args) {

        int a = Calculator.ADD.exe(3, 4);  //加法运算
        int b = Calculator.SUB.exe(3, 4);  //减法运算
        System.out.println(a+" "+b);

    }

}

可以看到,代码比之前简化了许多,而且可读性高,同时解决的类数目多以及类必须对外暴露等问题。所有说策略枚举方法是一个非常高效有用的方法。

时间: 2024-12-28 01:33:18

策略模式及优化的相关文章

JavaScript实现策略模式

在开篇之前先分享今天看到的一句关于设计模式的话:将不变的部分和变化的部分隔开是每个设计模式的主题 请大家自行感受这句话的精髓所在,并且思考学习设计模式究竟能给我们编程带来什么样的东西,欢迎大家在文章下面评(chui)论(shui),分享自己的宝贵见解.好了,回到今天的正题,JavaScript实现策略模式. 什么是策略模式 定义一系列的算法,把它们一个个封装起来,并且使它们可以相互转换.讲人话就是:我想去旅游,那么我可以选择不同的方法(策略)去达到我的目的--旅游.比如说坐飞机,走路,甚至是小黄

策略模式(Strategy )

为实现一个目的采用不同的方式都可实现,具体看要采取哪种方式. //接口 public interface Strategy {    public void algorithmInterface(); } public class  ConcreStrategyA implments Strategy {    public void  algorithmInterface() { System.out.println("策略A开始执行"); } } public class  Con

策略模式的学习之道

策略模式 1.需求分析: 一个考试系统,当考生的成绩通过后(成绩大于60分)会通过各种方式通知用户. 通知方式有:APP消息推送.短信.邮件.站内消息四种方式: 但是每种方式是否进行通知是要进行在表中配置的: 假设我们从表中查询后的对象如下: /** * 成绩对象 */ public class Score { //成绩 private int score; //是否使用app消息通知,使用0表示否,1表示是.下同 private int sendAPPMsg; //是否使用短信通知 priva

委派模式和策略模式

一.委派模式 委派模式(Delegate Pattern):指负责任务的调度和分配任务,跟代理模式很像,可以看做是一种特殊情况下的静态代理的全权代理,但是代理模式注重过程,而委派模式注重结果.(属于行为型模式,但它不属于GOF的23种设计模式之一.类名以Delegate和Dispatcher结尾的一般都是委派模式) 委派模式在Spring中应用非常多,大家常用的DispatcherServlet其实就用到了委派模式.现实生活中也常有委派的场景发生,例如:老板(Boss)给项目经理(Leader)

代码重构:用工厂+策略模式优化过多的if else代码块

最近在工作中优化了一段冗余的if else代码块,感觉对设计模式的理解和运用很有帮助,所以分享出来.鉴于原代码会涉及到公司的隐私,因此就不贴出来了.下面以更加通俗易懂的案例来解析. 假如写一个针对员工上班不遵守制度做相应惩罚的程序,比如,上班迟到:罚100:上班睡觉:罚1000:上班早退:警告:上班玩游戏:严重警告:上班谈恋爱:开除等,通常都会这样写: public class WorkPunish { public static void main(String[] agrs){ String

[一]Head First设计模式之【策略模式】(鸭子设计的优化历程)

public abstract class Duck { FlyBehavior flyBehavior; QuackBehavior quackBehavior; public Duck() { } public abstract void display(); public void performFly() { flyBehavior.fly(); } public void performQuack() { quackBehavior.quack(); } public void swi

对设计模式的总结之简单工厂与策略模式

前言 面向对象编程追求的本质-提高扩展性.可维护性.灵活性和复用性.合理利用面向对象6个原则,能够很好的达到要求.如何利用好就是至关重要的了,前人总结了23+个设计模式能够让初学者更容易学到其中的精髓,本文就说说我对本人对简单工厂模式.策略模式的见解. 简单工厂模式与策略模式 简单工厂模式 工作中,常常遇到需要做一个功能(鸭子),这个功能中含有可控个数的子操作功能(鸭子叫,鸭子跑,鸭子飞),而且子功能在不同的情况下处理方式又不相同(成年鸭子/小鸭子叫,成年鸭子/小鸭子跑,成年鸭子/小鸭子飞).我

【LabVIEW技巧】策略模式

前言 在之前的文章中,我们提到了如何学习OOP以及对应的简单工厂模式,由于时间比较长,我们先回顾一下之前讲到的一些内容,然后继续了解策略模式. 为什么学习OOP 在测控系统的软件开发过程中,我们LabVIEW工程师一直认为程序完成功能就可以了,但是随着程序的越来越复杂,我们发现很多情况下成型系统到后期无法添加功能或很难添加功能. 是什么阻碍了我们软件系统的开发?为什么在需求沟通不明确的前期,我们无法开发软件:在需求明确的后期,又无法对软件进行灵活修改. 如果大家仔细分析中国的四大发明,就会发现活

策略模式的孪生兄弟——对状态模式的深度复习总结

俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的总结知识点如下: 和策略模式的比较 状态模式概念和例子 应用场景 责任链模式和状态模式对比 一种代码优化的思路 java.util.Iterator里也有状态模式的影子 状态模式的优缺点 有限状态机及其应用 前面有总结——策略模式,之前早就觉得策略和状态设计模式有一些相似…… 接口的常用用法都有什么?策略设计模式复习总结 我知道策略模式是对象的行为模式,其实就是对一系列级别平等的算法的封装,它不关心算法实现,让客户端去动态的