Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle 'this' reference in decorator pattern

I have a problem in a class of mine that uses the decorator pattern.

The problem arises when the inner object uses the "this" reference in calls to other objects. This causes all calls from the object that received the "this" reference to be made directly to the inner object, without going through the outer first.

What is the usual way to solve this problem?

Thanks.

like image 339
monoceres Avatar asked Oct 12 '10 23:10

monoceres


People also ask

What problem is solved by the decorator pattern?

The problem of inheritance can be solved by using a decorator pattern where you can add functionality to an object at run time.

What is the decorator pattern example?

Example. The Decorator attaches additional responsibilities to an object dynamically. The ornaments that are added to pine or fir trees are examples of Decorators. Lights, garland, candy canes, glass ornaments, etc., can be added to a tree to give it a festive look.

How does the Decorator design pattern work?

Decorator patterns allow a user to add new functionality to an existing object without altering its structure. So, there is no change to the original class. The decorator design pattern is a structural pattern, which provides a wrapper to the existing class.

What is the decorator pattern used for?

The Decorator Pattern allows class behavior to the decorated dynamically. It's a structural design pattern as it's used to form large object structures across many disparate objects. The concept of decorator is that it adds additional attributes to an object dynamically.


2 Answers

Objects have an implicit value: their identity (can be tested by applying ==). When you wrap them, you effectively hide that identity (worse, you also expose a potentially misleading identity, the identity of the wrapper itself). So an obvious approach is compensating for this by exposing the identity of the object via another way - explicitly. E.g. you might introduce a method Object getIdentity(), that returns an object really representing the intended identity, and allowing applying == to it.

The huge downside though is that you still allow == on the decorator itself, e.g. a hazard that:

  • is natural enough to be tricked into it (identity == decorator instead of identity == decorator.getIdentity())
  • silently does the wrong thing (compare with a runtime exception - good luck debugging that)

The problem would be non-existent if, for example, objects had a method like:

protected Object getIdentity() {
    return this;
}

On which == operator would be defined, so a wrapper could also wrap the identity of the wrapped object, instead of replacing it with its own.

like image 149
Dimitris Andreou Avatar answered Oct 27 '22 03:10

Dimitris Andreou


In general, you can't. Unless you subclass your decorated class, your inner class will be free to call any method using itself as parameter, and there is no way to change it.

When using the decorator pattern, the decorator class is in charge of passing the this reference (referencing the decorator itself) to other methods. From my point of view, the decorator is the most similar thing to a proxy: the inner decorated object is completely wrapped into its decorator(s) and is not directly accessible. So, you must find by yourself a way to disallow your decorated object to directly access other objects and being able to pass this reference

like image 28
usr-local-ΕΨΗΕΛΩΝ Avatar answered Oct 27 '22 01:10

usr-local-ΕΨΗΕΛΩΝ