在 Ruby 中實現乙個訊號訂閱通知功能(一)

2021-10-01 11:01:39 字數 1638 閱讀 9301

為了實現模組之間的解耦,我需要乙個類似 qt 中的訊號槽機制 和 gdscript 中的訊號機制。

使用場景:

有乙個計數器和乙個顯示屏,當計數器更新時,需要顯示屏同步顯示更新的計數,後續可能需要將計數器的計數用於到其它地方。

先看看在沒有實現訊號訂閱機制時的**是怎麼樣寫的。

class counter

attr_accessor :value

def initialize(led_screen)

@led_screen = led_screen

enddef increment

@value = @value + 1

@led_screen.display(@value)

endendclass ledscreen

def display(content)

# 顯示到屏上,暫無實現

endendled_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個引數是附帶的訊息

endendclass 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 #"

# 更新到顯示屏上

display(value)

enddef display(content)

# 顯示到屏上,暫無實現

endend# testcase

counter = counter.new

counter.increment

led_screen = ledscreen.new

# 期望 ledscreen#on_value_changed 方法被呼叫

待續。

乙個用WCF實現Ruby中scaffold的想法

徵求意見 原因 ruby確實能夠極大的提高開發人員的效率,可是學起來要花費很長的時間。也許一種語言不能夠做到完美,可是我們要讓它盡量完美起來。想開發乙個外掛程式系統,也可以說是 生成器,使之能夠具有ruby on rails的scaffold功能。條件 給定資料庫連線字串 初步先以sql serve...

js實現乙個簡單的訂閱模式

訂閱模式應用非常廣泛,比如vue中的鉤子以及vuex的設計模式中都大量使用了訂閱模式。下面就簡單的演示一下。class event 事件佇列 註冊事件 發布 addeventlistener name,handler this handlers name push handler 存入事件 觸發事件...

ROS學習 在同乙個節點實現發布 訂閱訊息

在ros的應用中,常常會遇見乙個節點接收了某個資料後,經過處理再 出來。下面就這種情況給出在同乙個節點實現發布 訂閱訊息的例子。include ros ros.h include std msgs float64.h include class tl1 intmain int argc,char a...