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

前提

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

原理

bit数组的布局如下:

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

  • 优点:节省空间,理论上只需要占用最多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);
......

小结

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

参考资料:

  • sofa-bolt源码

(e-a-20210723 c-2-d)

实现Microbit开发板的WiFi点灯功能,需要以下步骤: 1.购买Microbit WiFi扩展板,这是一款可以在Microbit上添加WiFi功能的扩展板。 2.下载并安装MicroPython固件,这是一种用于Microbit的Python语言版本。 3.连接Microbit WiFi扩展板,并使用USB连接将Microbit连接到电脑。 4.使用编辑器,比如Mu编辑器,打开Microbit上的main.py文件。 5.编写代码,以实现WiFi点灯功能。下面是一份基本的代码示例: ``` from microbit import * import network # 设置WiFi连接 wifi_ssid = 'your_wifi_ssid_here' wifi_password = 'your_wifi_password_here' # 初始化网络连接 wlan = network.WLAN(network.STA_IF) wlan.active(True) # 连接WiFi wlan.connect(wifi_ssid, wifi_password) # 等待连接成功 while not wlan.isconnected(): pass # WiFi连接成功 display.show(Image.YES) while True: # 等待用户按下按钮A if button_a.was_pressed(): # 发送请求以点亮LED灯 import urequests response = urequests.get('https://maker.ifttt.com/trigger/light_on/with/key/your_ifttt_key_here') ``` 6.保存代码并重新启动Microbit。现在,当Microbit连接到WiFi并按下按钮A时,它将发送请求以点亮LED灯。您可以使用IFTTT服务来构建触发器,并将其与请求配对,以完成此部分。 注意:您需要在此代码中替换您自己的WiFi SSID、WiFi密码和IFTTT密钥。此外,您还需要在Microbit上安装urequests库,该库允许Microbit通过HTTP请求发送数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Throwable文摘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值