4

I occasionally write code like this when I want to replace small parts of an existing implementation:

public interface IFoo
{
    void Bar();
}

public class Foo : IFoo
{
    public void Bar()
    {
    }
}

public class ProxyFoo : IFoo
{
    private IFoo _Implementation;

    public ProxyFoo(IFoo implementation)
    {
        this._Implementation = implementation;
    }

    #region IFoo Members

    public void Bar()
    {
        this._Implementation.Bar();
    }

    #endregion
}

This is a much smaller example than the real life cases in which I've used this pattern, but if implementing an existing interface or abstract class would require lots of code, most of which is already written, but I need to change a small part of the behaviour, then I will use this pattern.

Is this a pattern or an anti pattern? If so, does it have a name and are there any well known pros and cons to this approach?

Is there a better way to achieve the same result? Rewriting the interfaces and/or the concrete implementation is not normally an option as it will be provided by a third party library.

1
  • Since you're doing the COM thing and putting an I in front of your interface name, I suppose it's worth mentioning that the first generation of COM developers called this pattern "inheritance by aggregation."
    – mjfgates
    Jun 12, 2012 at 16:41

2 Answers 2

7

Yep, this is a decorator pattern and it certainly has its place.

My only advice here would be not to call the class a proxy as some people might associate that with a proxy design pattern and get a bit confused. Proxies generally do not change behavior but rather serve as some kind of channel to the real object. This channel could be used for communications, authorization, caching or controlling/scheduling calls to the real object. In all instances, proxy wouldn't alter actual "business logic" of the real component but add some "out-of-band" qualities.

A decorator would implement the same interface, but it could add or remove business logic behavior that's actually being exposed to the client.

For example I work in video and we have presentation objects that expose information regarding live and recorded data available for a given video source. In certain places we only want to expose live video. In other places we want to expose only small segments of recorded video. Instead of recreating an entire presentation object for each of the special cases, we used "LiveOnlyPresentation" and "RecordedSegmentPresentation" decorators to override one function each and simply limit what the client can see.

6
  • But it's not changing behaviour, is it?
    – pdr
    Jun 12, 2012 at 15:43
  • @pdr: Can you define "it"? From OP: "but I need to change a small part of the behaviour". Pretty sure that's exactly what decorator does.
    – DXM
    Jun 12, 2012 at 15:45
  • Still, Decorator is a UI pattern. I don't think it fits this example.
    – pdr
    Jun 12, 2012 at 15:48
  • @pdr: UI is a typical example and the word "decorator" might be misleading, but same idea can be applied to anything. From Wiki: "By contrast, decorators are objects, created at runtime, and can be combined on a per-use basis. The I/O Streams implementations of both Java and the .NET Framework incorporate the decorator pattern."
    – DXM
    Jun 12, 2012 at 15:49
  • Take your point, but I'm still thinking that it falls under the Proxy pattern. Your description of a Proxy only really covers one of the four types listed here: oodesign.com/proxy-pattern.html Decorator, to my mind, implies something where you can, at runtime, wrap one or many layers of decoration around an object. The OP's example is specifically a design-time thing.
    – pdr
    Jun 12, 2012 at 16:02
2

I like to use this pattern for repository caching: you can separate the caching logic from the data-access logic, but since the expected contract is essentially the same (the method will return the data it's asked for, regardless of whether it's retrieved from a cache or the underlying repository), it can safely implement the same interface.

public interface IPersonRepository
{
    Person GetById(int personId);
}
public class PersonRepositoryCache : IPersonRepository
{
    private static ConcurrentDictionary<int, Person> cacheById = 
       new ConcurrentDictionary<int, Person>();
    private IPersonRepository _repository;
    public PersonRepositoryCache(IPersonRepository repository)
    {
        _repository = repository;
    }
    public Person GetById(int personId)
    {
        return cacheById.GetOrAdd(personId, id => _repository.GetById(id));
    }
}

You'll want to be wary that you don't use this pattern to change the contractual behavior expected of the interface, as this would violate the Liskov Substitution Principle. Only change implementation details, while ensuring that users' expectations of the class's behavior are preserved.

To get the most out of this pattern, consider using an IoC container, so that classes that use the interface are unaware of the implementation details.

This pattern is used effectively by Aspect-Oriented Programming to add behaviors like logging to method calls. Again, these are behaviors that do not alter the contractual behavior of the method in question.

Hat-tip to DXM for pointing out that this is called the Decorator Pattern.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.