これはオブザーバー パターンにとっては良い状況のように思えます。これはルビーでのサンプルです:
require 'observer'
class Node
attr_accessor :id
@@current_node_id = 0
def initialize
@@current_node_id += 1
id = @@current_node_id
end
include Observable
attr_reader :value
protected
def value=(new_value)
return if @value == new_value
old_value = @value
@value = new_value
changed
notify_observers(id, old_value, @value)
end
end
class ValueNode < Node
def initialize(initial_value)
super()
@value = initial_value
end
def value=(new_value)
super(new_value)
end
end
class SumNode < Node
def initialize(*nodes)
super()
@value = nodes.map(&:value).inject(0, &:+)
nodes.each do |node|
node.add_observer(self)
end
end
def update(id, old_value, new_value)
self.value = self.value - old_value + new_value
end
end
def test
v1 = ValueNode.new 4
v2 = ValueNode.new 8
sum = SumNode.new(v1, v2)
sum2 = SumNode.new(v1, sum)
v2.value = 10
p sum.value
p sum2.value
end
test()
SumNode
の値が要求されるたびに再計算されるのではなく、その値ノードの 1 つが更新されると更新されることに注意してください。これは再帰的に機能するため、内部SumNodes
も更新をトリガーします。通知にはノードの一意が含まれているため、式を含むものなど、id
より複雑な型を記述することができます。Node
Observable の詳細については、http: //www.ruby-doc.org/stdlib/libdoc/observer/rdoc/index.html を参照してください。