策略模式

作者: GeekerLou | 来源:发表于2020-03-08 10:20 被阅读0次

    策略模式

    含义

    策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

    一般情况下我们是将一种行为写成一个类方法,比如计算器类中有加、减、乘、除四种方法,而策略模式则是将每一种算法都写成一个类,然后动态地选择使用哪一个算法。

    使用案例

    1. 默认主题与自定义主题功能的实现

    2. Shiro提供三种验证策略

    优缺点比较

    1. 优点
      讲完上面的例子,优点已经十分明显了,那就是遵循了开闭原则,扩展性良好。

    2. 缺点
      随着你的策略增加,你的类也会越来越多。
      所有的策略类都要暴露出去,所以如果你在实际开发中使用了策略模式,一定要记得写好文档让你的伙伴们知道已有哪些策略。就像 Shiro 默认提供了三种验证策略,就必须在文档中写清楚,否则我们根本不知道如何使用。
      当然,权衡利弊,跟优点比起来,这些缺点都不算事儿。

    示例

    示例1:计算器

    首先需要一个算法框架的接口,我们顶一个Operation类作为算法族的集合,其中有一个 示例的操作方法doOperation

    /**
     * 策略模式组件:算法框架,由此将衍生出一个算法族
     */
    public interface Operation {
        int doOperation(int num1, int num2);
    }
    

    定义一个计算器类,作为操作所有功能算法的入口:

    /**
     * 计算器类,操作Operation算法的提供者
     */
    public class Calculator {
        private Operation operation;
    
        public void setOperation(Operation operation) {
            this.operation = operation;
        }
    
        public int doOperation(int num1, int num2) {
            return this.operation.doOperation(num1, num2);
        }
    
    }
    

    定义一个加法操作OperationAdd

    /**
     * 加法操作,Operation算法的实现类之一
     */
    public class OperationAdd implements Operation {
        @Override
        public int doOperation(int num1, int num2) {
            return num1 + num2;
        }
    }
    

    定义一个减法操作OpreationSub

    /**
     * 减法操作,Opreation算法的实现类之一
     */
    public class OpreationSub implements Operation {
        @Override
        public int doOperation(int num1, int num2) {
            return num1 - num2;
        }
    }
    

    示例2:主题

    首先,定义一个算法框架ThemeInterface用来表示操作主题相关的方法的签名的集合。

    /**
     * 定义主题应当具有的功能接口
     * 所有的主题都应当实现该接口
     */
    public interface ThemeInterface {
        void showTheme();
    }
    

    接下来,定义一个主题管理器类ThemeManager,它是用以操作主题相关功能的入口,可以理解为是主题管理器的入口类,里面提供了所有支持的操作主体的方法:

    public class ThemeManager {
    
        private ThemeInterface theme;
    
        public void setTheme(ThemeInterface theme) {
            this.theme = theme;
        }
    
        public void showTheme() {
            this.theme.showTheme();
        }
    }
    

    然后我们可能有一个默认的主题DefaultTheme:

    /**
     * 默认主题
     */
    public class DefaultTheme implements ThemeInterface {
        @Override
        public void showTheme() {
            //此处设置主题颜色,背景,字体等
            System.out.println("显示默认主题");
        }
    }
    

    我们也可以切换到某个自定义的主题:

    public class MyTheme implements ThemeInterface {
        @Override
        public void showTheme() {
            System.out.println("我的自定义主题");
        }
    }
    

    单元测试

    import com.netease.learn.designPattern.strategy.calculator.Calculator;
    import com.netease.learn.designPattern.strategy.calculator.OperationAdd;
    import com.netease.learn.designPattern.strategy.theme.DefaultTheme;
    import com.netease.learn.designPattern.strategy.theme.MyTheme;
    import com.netease.learn.designPattern.strategy.theme.ThemeManager;
    import org.junit.Test;
    
    public class StrategyTest {
    
        @Test
        public void test1() {
            Calculator calculator = new Calculator();
            calculator.setOperation(new OperationAdd());
            int result = calculator.doOperation(1, 2);
            System.out.println(result);
        }
    
        @Test
        public void test2() {
            ThemeManager themeManager = new ThemeManager();
    
            themeManager.setTheme(new DefaultTheme());
            themeManager.showTheme();
    
            themeManager.setTheme(new MyTheme());
            themeManager.showTheme();
        }
    }
    

    参考资料

    1. 代码仓库-策略模式

    相关文章

      网友评论

        本文标题:策略模式

        本文链接:https://www.haomeiwen.com/subject/thtddhtx.html