基于BIT数组实现全局功能开关

简介: 某一天巧合打开了sofa-bolt项目,查找部分源码,看到了项目中使用bit数组实现功能开关的特性,感觉这种方式可以借鉴,于是写下这篇文章。

前提



某一天巧合打开了sofa-bolt项目,查找部分源码,看到了项目中使用bit数组实现功能开关的特性,感觉这种方式可以借鉴,于是写下这篇文章。


原理



bit数组的布局如下:

微信截图_20220513210221.png


由于每个bit都可以表示1或者0,刚好对应于开关的ONOFF。只需要定义好每个开关所在的bit数组下标和开关的状态(ON = 1或者OFF = 0),通过判断不同开关下标所在的bit即可判断开关的状态:

微信截图_20220513210227.png


  • 优点:节省空间,理论上只需要占用最多2n位的内存(n为开关的数量,这里考虑扩容,扩容让bit数组长度为原来的2倍)
  • 缺点:暂时没发现


实现



JDK中的bit数组可以直接使用BitSet。首先定义开关定义SwitchDef


public class SwitchConst {
    public static final boolean ON = true;
    public static final boolean OFF = false;
}
@RequiredArgsConstructor
@Getter
public enum SwitchDef {
    /**
     * 启用HTTPS
     */
    ENABLE_HTTPS(0, SwitchConst.ON, "启用HTTPS"),
    /**
     * 启用异步
     */
    ENABLE_ASYNC(1, SwitchConst.OFF, "启用异步"),
    ;
    /**
     * 下标
     */
    private final int index;
    /**
     * 默认状态
     */
    private final boolean defaultStatus;
    /**
     * 描述
     */
    private final String description;
    @Override
    public String toString() {
        return String.format("SwitchDef(name=%s,description=%s)", name(), description);
    }
}
复制代码


接着定义开关接口Switch


public interface Switch {
    /**
     * 启用
     *
     * @param switchDef switchDef
     */
    void turnOn(SwitchDef switchDef);
    /**
     * 关闭
     *
     * @param switchDef switchDef
     */
    void turnOff(SwitchDef switchDef);
    /**
     * 判断状态
     *
     * @param switchDef switchDef
     * @return boolean
     */
    boolean status(SwitchDef switchDef);
}
复制代码


最后编写开关实现BitSetSwitch和客户端代码:


public enum BitSetSwitch implements Switch {
    /**
     * 单例
     */
    X;
    BitSetSwitch() {
        init();
    }
    private final BitSet switches = new BitSet();
    @Override
    public void turnOn(SwitchDef switchDef) {
        switches.set(switchDef.getIndex(), SwitchConst.ON);
    }
    @Override
    public void turnOff(SwitchDef switchDef) {
        switches.clear(switchDef.getIndex());
    }
    @Override
    public boolean status(SwitchDef switchDef) {
        return switches.get(switchDef.getIndex());
    }
    private void init() {
        Stream.of(SwitchDef.values()).forEach(item -> switches.set(item.getIndex(), item.isDefaultStatus()));
    }
    public static void main(String[] args) {
        Switch s = BitSetSwitch.X;
        s.turnOn(SwitchDef.ENABLE_HTTPS);
        s.turnOff(SwitchDef.ENABLE_ASYNC);
        System.out.printf("开关[%s],状态:%s%n", SwitchDef.ENABLE_HTTPS, s.status(SwitchDef.ENABLE_HTTPS));
        System.out.printf("开关[%s],状态:%s%n", SwitchDef.ENABLE_ASYNC, s.status(SwitchDef.ENABLE_ASYNC));
    }
}
复制代码


执行该main方法后控制台输出如下:

开关[SwitchDef(name=ENABLE_HTTPS,description=启用HTTPS)],状态:true
开关[SwitchDef(name=ENABLE_ASYNC,description=启用异步)],状态:false
复制代码


仿真场景(伪代码)如下:


Switch s = BitSetSwitch.X;
String uri = "www.throwx.cn";
String schema = "http";
if (s.turnOn(SwitchDef.ENABLE_HTTPS)){
    schema = "https";
}
HttpClint ch = new DefaultHttpClient();
if (s.turnOn(SwitchDef.ENABLE_ASYNC)){
    ch = new AsyncHttpClient();
}
Result r = ch.executeRequest(schema + uri);
......
复制代码


小结



在阅读一些主流框架源码的时候,可以借鉴一些设计合理的方案应用到自身的日常开发中。


参考资料:


相关文章
|
监控 Java 索引
ES 生产中10个常见参数阈值(默认最大值)操作及优化解决方案
ES 生产中10个常见参数阈值(默认最大值)操作及优化解决方案
ES 生产中10个常见参数阈值(默认最大值)操作及优化解决方案
|
XML 安全 Java
自定义PMD检测的类型集合(详解)
自定义PMD检测的类型集合(详解)
自定义PMD检测的类型集合(详解)
|
5月前
LabVIEW以编程方式将VI控件值重置为默认值
LabVIEW以编程方式将VI控件值重置为默认值
297 2
|
4月前
|
运维 Serverless 数据处理
函数计算产品使用问题之设置了两个路由,如何设置优先级
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
UE4 更新资源时修改导入设置
UE4 更新资源时修改导入设置
93 0
UE4 更新资源时修改导入设置
|
5月前
|
存储
Qt更新组件出现(“要继续此操作,至少需要一个有效且已启用的储存库”)
Qt更新组件出现(“要继续此操作,至少需要一个有效且已启用的储存库”)
233 0
Qt更新组件出现(“要继续此操作,至少需要一个有效且已启用的储存库”)
实验:MSP430F249 数码管计数到60自动清零(详细注释)
实验:MSP430F249 数码管计数到60自动清零(详细注释)
90 0
ookie 值的修改方案
ookie 值的修改方案
87 0
keil动态语法检测开关,去除红×
keil动态语法检测开关,去除红×
190 0
西门子S7-1200PLC变量表如何使用?如何声明、选用、显示、定义、更改变量?变量保持性如何设置?
在S7-1200 CPU的编程理念中,特别强调符号寻址的使用,在开始编写程序之前,用户应当为输入、输出、中间变量定义相应的符号名,也就是标签。具体步骤如下:
西门子S7-1200PLC变量表如何使用?如何声明、选用、显示、定义、更改变量?变量保持性如何设置?