2

I recently learned about the decorator-pattern to dynamically extend existing behaviour. So I have this code:

IMyInterface b = new A();
if(someCondition)
    b = new B(b);
if(secondCondition)
    b = new C(b);

and so on, where all classes A, B and C implement IMyInterface and B and C are the decorators. So the final request for a method might be handled by up to three instances in the above example.

However I now want to inject a decorator into my code, because I have some plugin-mechanism which allows me to seperate product-code from project-specific code. This is why I don´t even know anything of B and C. So I want a way that returns a decorated instance of my interface, in a way that I can chain multiple plugins and thus multiple decorators:

IMyInterface b = new A();
/* collect the decorators from all plugins and chain them to get the final instance */

Has anyone a good idea on how to create the instances?

2

1 Answer 1

2

Well if you don't like directly knowing which decorators you're composing when you compose them you could try a refactoring: replace conditional with polymorphism.

Give each decorator a factory class for it's construction code to live in:

class MyInterfaceFactoryB : MyInterfaceFactory { 
    IMyInterface Decorate(IMyInterface a) { 
        return new B(a); 
    } 
}
class MyInterfaceFactoryC : MyInterfaceFactory { 
    IMyInterface Decorate(IMyInterface a) { 
        return new C(a); 
    } 
}

Populate a list with the factories. Each plugin could contribute to this.

List<MyInterfaceFactory> decorators = new List<MyInterfaceFactory>();

decorators.add(new MyInterfaceFactoryB());
decorators.add(new MyInterfaceFactoryC());

Now construct the decorators.

IMyInterface chain = new A();
foreach (MyInterfaceFactory decorator in decorators) {
    chain = decorator.Decorate(chain);
}

And the chain is ready to be used.

This should let you separate code that knows about A from code that knows about B and C.

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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