我想装饰(装饰器设计模式)一个公共基类,但我需要装饰的方法受到保护。见例:
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
}
这个挑战有解决方案吗?
答案 0 :(得分:6)
如果您将AbstractActor
和ActorDecorator
放在同一个包中,则可以访问受保护的方法。
答案 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()
?
希望有所帮助。