在 Ruby 中实现一个信号订阅通知功能(一)

为了实现模块之间的解耦,我需要一个类似 Qt 中的信号槽机制 和 GDScript 中的信号机制

使用场景:

有一个计数器和一个显示屏,当计数器更新时,需要显示屏同步显示更新的计数,后续可能需要将计数器的计数用于到其它地方。

先看看在没有实现信号订阅机制时的代码是怎么样写的。

class Counter
    attr_accessor :value

    def initialize(led_screen)
        @led_screen = led_screen
    end

    def increment
        @value = @value + 1
        @led_screen.display(@value)
    end
end

class LedScreen
    
    def display(content)
        # 显示到屏上,暂无实现
    end
end

led_screen = LedScreen.new
counter = Counter.new(led_screen)
counter.increment

以上代码可以基本工作,但是我对这样的代码不满意。在对计数器 Counter 类进行单元测试时,需要引入 LedScreen 类,增加了复杂性。另外当有新的需求时,需要修改 Counter#increment 方法。

我不喜欢这样,我准备使用信号机制实现解耦。当需要将计数器 Counter 的值显示到其它地方,也不需要改动 Counter 的代码, 计数器 Counter 就只是做它本应该做的事情。

首先不考虑具体的实现,先把我设想的 API 接口初步定下来,后续考虑使用 Ruby 的魔法来实现出来。用下面的代码来说明:

class Counter
    attr_accessor :value
    register_signal :value_changed
    
    def increment
        @value = @value + 1
        emit_signal :value_changed, @value
        # emit_signal 第0个参数是信号名,第1个参数是附带的消息
    end
end

class LedScreen
    # 默认调用 on_value_changed
    # 也可以附加一个参数用来指定信号订阅的方法
    # eg: subscribe_signal :value_changed, :when_value_changed
    subscribe_signal :value_changed 

    def on_value_changed(value)
        puts "Got counter value changed to #{value}"
        # 更新到显示屏上
        display(value)
    end

    def display(content)
        # 显示到屏上,暂无实现
    end
end

# Testcase

counter = Counter.new
counter.increment
led_screen = LedScreen.new
# 期望 LedScreen#on_value_changed 方法被调用

待续。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值