Java Decorator模式:我可以装饰受保护的方法吗?

时间:2011-04-21 10:35:05

标签: java design-patterns decorator

我想装饰(装饰器设计模式)一个公共基类,但我需要装饰的方法受到保护。见例:

public class AbstractActor {
   public void act(){...}      //Delegates its actions to doAct() based on some internal logic
   protected void doAct(){...}
}

子类意味着覆盖doAct(),我需要在那里注入一些功能。我可以覆盖doAct,但我的装饰器类无法访问正在装饰的实例上的受保护方法doAct()。例如:

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
}

这个挑战有解决方案吗?

4 个答案:

答案 0 :(得分:6)

如果您将AbstractActorActorDecorator放在同一个包中,则可以访问受保护的方法。

答案 1 :(得分:0)

你如何扩展你想要装饰的类,并提供一个调用受保护函数的公共函数(你可以访问它),然后装饰扩展类? 所以在你的例子中:

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
}

答案 2 :(得分:0)

我认为使用相同的包名是最好的答案,但我还有一个突然出现在我脑海中的评论。

应该可以使用面向方面编程(例如AOP,AspectJ)来为doAct()方法注入建议。由于我在Spring环境中工作并且可以使用AOP编程,因此我可能会考虑使用此功能。

我添加了这个答案作为一点思考,我还没有使用AOP来解决这个问题。

答案 3 :(得分:-1)

当一个类设计师保持一个方法受保护时,它应该保持这种方式!如果你以这种方式违反封装,那就是为每个人设置非常糟糕的编程示例,为课堂消费者带来更多麻烦。

话虽如此,在您的情况下,是什么阻止您在重写act()调用中注入您的代码?无论如何,它会调用受保护的方法doAct()

希望有所帮助。