6

Suppose I have a class uicontrolWrapper, which is a wrapper for a uicontrol (but does not subclass it). The uicontrol stuff is kept in a private property for uicontrolWrapper. Basically, I want to be able to do set/get against the wrapper, and calls would feed into uicontrol.

I could do this:

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

but hardcoding like this is obviously pretty ugly.

Or, I could do 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

The whole point is to avoid violating the Law of Demeter by not "reaching into" the property we're trying to adjust.

I don't know if this is a design pattern, but I've used this type of thing to wrap objects of different types when subclassing is for some reason or another inappropriate. (For instance, the matlab.ui.control.UIControl class is Sealed and cannot be subclassed.) Does this have an actual name and intended typical use?

Community
  • 1
  • 1
Dang Khoa
  • 5,693
  • 8
  • 51
  • 80
  • Kind of reminds me of the [Decorator](http://www.oodesign.com/decorator-pattern.html). It basically gives you the possibility to add functionality to the extended class. Not sure if this is your case though. Never seen matlab before, so it's kind of confusing to read for me. – Bono Feb 23 '15 at 14:30
  • why the downvote? I'd be happy to edit to make this question better. – Dang Khoa Feb 23 '15 at 14:33
  • 1
    Wasn't me. I upvoted against the downvote, because it seems like a good clear question to me. – Bono Feb 23 '15 at 14:34

2 Answers2

3

This is the Decorator Pattern -- creating a tool that decorates new functionality onto existing objects (at possibly many different times) specifically without affecting any other instances of the same type (or affecting them in an explicit way if desired).

This differs from Proxy pattern in the sense that you're not defering the task of dispatching the right operation to the proxy, you're actually grafting new functionality onto the object.

ely
  • 74,674
  • 34
  • 147
  • 228
  • In reading up on the pattern, it seems that the Decorator class inherits from the class being decorated. Is this necessary to do, and if so, why? (My `uicontrolWrapper` does not subclass `uicontrol`, just keeps it as a property, for instance.) – Dang Khoa Feb 23 '15 at 15:14
  • It's not necessary, for example check out how the decorator pattern works in Python. – ely Feb 23 '15 at 15:17
  • Better implementations use interfaces to implement this pattern. Sadly MATLAB doesn't really have these so you're forced into bodging it into an inheritance tree. The perfect impl is an interface that captures the contract of the object being decorated, then a base abstract class that accepts an instance of said interface and does all the forwarding to the nested object. Then all the decorators inherit from the base decorator and override as they choose. – Quibblesome Feb 06 '20 at 16:38
  • I'd argue that kind of use of nested inheritance is a bad design pattern generally (like most canonical design patterns). Deeply nested inheritance is a scourge of software design. – ely Feb 06 '20 at 22:31
1

I believe you're asking about the Proxy design pattern here (provide an interface to other objects by creating a wrapper class as the proxy).

A couple of its benefits are adding security access and simplifying the API to the wrapped object (the proxy can provide a simple API so that the client code does not have to deal with the complexity of the object of interest).

Jeb
  • 3,689
  • 5
  • 28
  • 45
  • It's not proxy pattern, it's decorator pattern. Proxy manages a dispatching interface, not the decoration of new functionality grafted *onto* something. – ely Feb 23 '15 at 14:31
  • Yes, but all a decorator is is a "smart" proxy, so if needed the OP can just add extensions on. The basis is a proxy/delegate – Jeb Feb 23 '15 at 14:33
  • No, there is an important reason why Decorator and Proxy are considered different patterns. It might be annoying bike-shedding to debate about words like that, but it matters. Otherwise, with most software design patterns, you can make up vague, hand-wavy reasons why virtually any pattern you pick is actually some special form or special case of virtually any other pattern you pick. It's important to avoid these urges to say "well, it's just a special case of ___" – ely Feb 23 '15 at 14:35
  • Well I would say there isn't a tenuous link between the two (and I'm not into bike-shedding). The OP didn't explicitly say they were extending the functionality of the wrapped object. Anyway, this is quite useful for the OP at least: http://stackoverflow.com/questions/350404/how-do-the-proxy-decorator-adapter-and-bridge-patterns-differ – Jeb Feb 23 '15 at 14:40