Decorator Pattern: The Leaking This Problem

With all of the substitution patterns, the principle is that the proxied target doesn’t need to be aware of the proxying object.  That’s pretty achievable if what you’re trying to do is provide a local proxy to a remote object.  However, when you’re using a decorator, things get a bit trickier.  Welcome to the “leaking this” problem.

This is leaking

To start with an easy example, what if the target does this:

return this;

What do you do?  Well, it’s not obvious, but typically you’ll get the decorator to return itself.  This case is relatively easy to spot.  But how about if it does this

return this.AnotherMethodOnInterface();

Here you can’t intercept the call at all.  Maybe you didn’t want to, but this is the case in which inheritance can actually be more useful than composition.  But there’s an even worse case:

return new SomeOtherObject(this);

Okay, well your decorator can give SomeOtherObject a decorator as well, and often that’s what you wanted to do.  But sometimes you actually wanted SomeOtherObject to take a dependency on the decorator, and that can’t be achieved.  Using a factory doesn’t help, since it’s typically a constructor dependency and as such unaware of the decorator.*

It just gets worse.  What if your target raises an event?  You’re going to have to make sure the sender points to the decorator.  The target could stick itself into a global variable (ugly, but possible).  So what’s the solution?  Here’s the thing: there isn’t one.  There are solutions for specific cases, but there’s no general way of replacing an object with a decorated version.  Sometimes, you’ve just got to redesign your target object to make sure you get the behaviour you want.

Why Isn’t This a Problem For Remote Proxies?

You might be thinking “but I’ve been using Remoting/WCF/RMI for years and I’ve never had a problem”.  And you’d be right.  The thing is: proxies don’t change behaviour, so you never encounter a position in which using the unproxied version would cause an issue.  The original object stays on the server, the proxy stays on the client.  If you take a look at the examples above, it’s really easy to answer the question “What should the proxy do?”

If you think that it’s painful to deal with hand-written decorators, wait until you try to build a framework for decorators.  Castle’s InterfaceProxyWithTarget and InterfaceProxyWithTargetInterface** methods are exactly that: general ways of writing decorators.  Anyone who uses DynamicProxy runs into the problem sooner or later.  The knee jerk reaction is that there’s something wrong with DynamicProxy.  Later on you realize it’s a limitation of the programming language: there’s simply no expressing what you actually wanted to achieve.

*You could pass the factory in as a function parameter, but you’d typically have to redesign your target to achieve this.

**Read about the difference on Krzysztof’s blog.  Read about how leaking this pertains to Dynamic Proxy specifically here.

Published by

Julian Birch

Full time dad, does a bit of coding on the side.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s