Шаблон Java Decorator: Могу ли я украсить защищенный метод? - PullRequest
5 голосов
/ 21 апреля 2011

Я хочу Украсить (шаблон проектирования 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 ]

6 голосов
/ 21 апреля 2011

Если вы поместите AbstractActor и ActorDecorator в один и тот же пакет, вы сможете получить доступ к защищенному методу.

0 голосов
/ 22 апреля 2011

Я думаю, что использование одного и того же имени пакета - лучший ответ, но у меня в голове появился еще один, который я прокомментирую.

Должна быть возможность использовать Аспектно-ориентированное программирование (например, AOP, AspectJ) для внедрения рекомендаций относительно метода doAct (). Поскольку я работаю в среде Spring и имею доступ к программированию AOP, я могу изучить использование этой функции.

Я добавил этот ответ как пищу для размышлений, мне еще предстоит использовать AOP для решения этой проблемы.

0 голосов
/ 21 апреля 2011

Когда разработчик класса сохраняет метод защищенным, он должен оставаться таким! Если вы нарушите инкапсуляцию таким образом, то это будет очень плохим примером программирования для всех, и больше проблем для потребителей класса.

Сказав, что в вашем случае что мешает вам ввести свой код в переопределенном вызове act()? Что в любом случае вызывает ваш защищенный метод doAct()?

Надеюсь, это поможет.

0 голосов
/ 21 апреля 2011

как насчет того, чтобы расширить класс, который вы пытаетесь украсить, и предоставить публичную функцию, которая вызывает защищенную функцию (к которой у вас будет доступ), а затем украсить расширенный класс?так в вашем примере:

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
}
...