策略模式

作者: 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