假设我有一个类uicontrolWrapper
,它是uicontrol
的包装器(但不是它的子类)。 uicontrol
内容保存在uicontrolWrapper
的私有财产中。基本上,我希望能够针对包装器执行set/get
,并且调用将提供给uicontrol
。
我可以这样做:
classdef uicontrolWrapper < handle
properties (Access = private)
uic
end
properties (Dependent)
Style
String
Value
...
end
methods
function set.Style(obj, val)
obj.uic.Style = val;
end
function val = get.Style(obj)
val = obj.uic.Style;
end
...
end
但像这样的硬编码显然很难看。
或者,我可以dynamically generate properties dependent on what I'm trying to wrap:
classdef uicontrolWrapper < dynamicprops
properties (Access = private)
uic
end
methods
function obj = uicontrolWrapper(hObj)
obj.uic = hObj;
cellfun(@(prop) obj.createProperty(prop, fields(get(hObj));
end
function createProperty(obj, prop)
p = addprop(obj, prop);
p.Dependent = true;
p.SetMethod = @setUicontrolProp;
p.GetMethod = @getUicontrolProp;
function setUicontrolProp(obj, val)
obj.uic.(prop) = value;
end
function val = getUicontrolProp(obj)
val = obj.uic.(prop);
end
end
end
end
重点是避免违反Law of Demeter而不是&#34;进入&#34;我们试图调整的财产。
我不知道这是否是一种设计模式,但是当子类化由于某种原因或另一种不合适时,我已经使用这种类型的东西来包装不同类型的对象。 (例如,matlab.ui.control.UIControl
类是Sealed
并且不能被子类化。)这是否具有实际名称和预期的典型用途?
答案 0 :(得分:3)
这是Decorator Pattern - 创建一个工具,可以在现有对象上(可能在很多不同的时间)修饰新功能,而不会影响同一类型的任何其他实例(或者如果需要,可以以明确的方式影响它们) )。
这与代理模式的不同之处在于您不会将正确操作的任务推迟到代理,您实际上将新功能移植到对象上。
答案 1 :(得分:1)
我相信你在这里询问Proxy设计模式(通过创建一个包装类作为代理提供其他对象的接口)。
它的一些好处是添加安全访问并简化包装对象的API(代理可以提供简单的API,以便客户端代码不必处理感兴趣对象的复杂性)。