MATLAB Answers

Translated by

このページのコンテンツは英語から自動翻訳されています。自動翻訳をオフにする場合は「<a class="turn_off_mt" href="#">ここ</a>」をクリックしてください。

Cedric Wannaz
0

Should I (and how to) avoid "forests" of listeners in nested OOP structure.

Cedric Wannaz
さんによって質問されました 2017 年 12 月 18 日
最新アクティビティ Cedric Wannaz
さんによって 編集されました 2017 年 12 月 19 日
Dear all,
System < handle, with properties System.grids and System.result
Grid < handle, with property Grid.layers
Layer < handle, with property Layer.gridCells
GridCell < handle, with property GridCell.area
where each class implements a property that is a cell array of objects of the class "below", i.e. System.grids={Grid obj #1,..}, Grid.layers={Layer obj #1,..} and Layer.gridCells={GridCell obj #1,..}. Property System.result is built/computed for a specific set of grids (and hence layers and grid cells). Its value must therefore be updated each time a grid or one the grids' layer or one of the layers' cell is updated (e.g. the area). EDIT 1 - If:
gc = system.grids{2}.layers{10}.gridCells{15200} ;
the following:
gc.area = 147 ;
should trigger an update of system.result.
In a less nested context, e.g. if updating a grid would be done through a basic set access to System.grids such as:
system.grids{3} = newGrid ;
I could manage triggering the update of result through a setter for the grids property. In a little more nested context, e.g. if layers can be updated without replacing Grid objects, through:
system.grids{3}.layers{1} = newLayer ;
I could set the layers property of Grid observable:
classdef Grid < handle
properties( SetObservable = true )
layers
end
..
an add listeners to the System object bound to each grid layers property and to the 'PostSet' event. Or better, I can define an event 'updated' in each class Grid, Layer, and GridCell, that would back-propagated to the System object through a chain of listeners: EDIT 2017/12/19 @ 19:30 UTC, e.g.:
classdef Grid < Cascadable
properties
layers
end
methods
function obj = Grid()
obj = obj@Cascadable() ;
end
function addLayer( obj, layer )
obj.layers{end+1} = layer ;
addlistener( layer, 'updated', ...
@(src, evnt) eventHandler_updated( obj, src, evnt )) ;
obj.eventHandler_updated() ;
end
end
end
with
classdef Cascadable < handle
events
updated
end
methods
function obj = Cascadable()
end
function eventHandler_updated( obj, varargin )
fprintf( '%s updated\n', class( obj )) ;
obj.notify( 'updated' ) ;
end
end
end
and an event handler in System that does a little more work, e.g. recomputing result.
While this last approach seems to be "clean enough", it requires adding setters that call NOTIFY for all relevant properties in each class, or overloading SUBSASGN for that purpose, or defining 'PostSet' listeners for all relevant properties of "self" (just for avoiding implementing a lot a setters and instead defining a single event handling method for all properties). This seems to be cumbersome and to defeat the purpose of events/listeners.
Is there a cleaner way? Did I miss an important mechanism, like a 'CascadedPostSet' event?
Cheers,
Cedric

  0 件のコメント

サインイン to comment.

0 件の回答


Translated by