Java Decorator Pattern: Can I decorate a protected method?
I want to Decorate (Decorator design pattern) a common base class, but the method I need to Decorate is protected. See example:
public class AbstractActor {
public void act(){...} //Delegates its actions to doAct() based on some internal logic
protected void doAct(){...}
}
Subclasses are meant to override doAct(), I need to inject some functionality there. I can override doAct, but my decorator class can't access the protected method doAct() on the instance being decorated. Example:
public class ActorDecorator extends AbstractActor {
AbstractActor decoratedInstance;
public ActorDecorator(AbstractActor decoratedInstance){
this.decoratedInstance = decoratedInstance;
}
protected void doAct(){
//Inject my code
decoratedInstance.doAct(); //Can't call protected method of decoratedInstance
}
//Other decorator methods
}
Is there some solution for this cha开发者_如何学JAVAllenge?
If you put AbstractActor
and ActorDecorator
in the same package, you will be able to access the protected method.
how about you extend the class you are trying to decorate and provide a public function that calls the protected function (to which you will have access to) and then decorate the extended class? so in your example:
public class ToDecorateActor extends AbstractActor {
public void publicAct() {
doAct();
}
}
public class ActorDecorator {
ToDecorateActor decoratedInstance;
public ActorDecorator(ToDecorateActor decoratedInstance){
this.decoratedInstance = decoratedInstance;
}
protected void doAct(){
//Inject my code
decoratedInstance.publicAct();
}
//Other decorator methods
}
I think using the same package name is the best answer, but I had one more that popped into my own mind that I'll comment on.
It should be possible to use Aspect Oriented Programming (AOP, AspectJ for example) to inject advice around the doAct() method. As I am working in a Spring environment and have AOP programming available I may look into using this functionality.
I've added this answer as a bit of food for thought, I've yet to use AOP to deal with this problem.
When a class designer keeps a method protected then it is supposed to remain that way! If you violate encapsulation this way then that is setting very bad programming example for everyone and more trouble for consumers of class.
Having said that, in your case, what stops you from injecting your code in the overriden act()
call? Which anyways does call your protected method doAct()
?
Hope that helps.
精彩评论