2011-04-21 3 views
5

나는 에 장식한다 (데코레이터 설계 패턴)은 공통 기본 클래스이지만, 내가 필요한 방법은 장식이 보호되어있다. 예를 참조하십시오Java Decorator 패턴 : 보호 된 메소드를 꾸밀 수 있습니까?

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

서브 클래스는 doAct()를 오버라이드 (override)하기위한 것입니다, 나는 거기에 몇 가지 기능을 주입 할 필요가있다. 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 
} 

이 챌린지에 대한 해결책이 있습니까?

답변

6

AbstractActorActorDecorator을 동일한 패키지에 넣으면 보호 된 방법에 액세스 할 수 있습니다.

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 
} 
+0

여기서 문제는 ToDecorateActor의 인스턴스가 아닌 DecorActor (및 하위 클래스가 여러 개)의 인스턴스를 가지고 있다는 점입니다. 예를 들어, hollywoodActor (HollywoodActor가 AbstractActor를 확장)라고 주어진 경우 새 ActorDecorator (hollywoodActor)를 호출 할 수 없습니다. –

+0

나는이 대답을 좋아하지 않는다. 기본적으로 보호 된 메소드를 공용 메소드로 변경합니다. –

+0

클래스 디자이너가 메서드를 보호 한 상태로 유지하면 해당 메서드는 그대로 유지됩니다. 이 방법으로 캡슐화를 위반하면 모든 사람에게 매우 나쁜 프로그래밍 예제를 설정하고 클래스 소비자에게 더 많은 문제가 발생합니다. – Nilesh

-1

! 이 방법으로 캡슐화를 위반하면 모든 사람에게 매우 나쁜 프로그래밍 예제를 설정하고 클래스 소비자에게 더 많은 문제가 발생합니다.

그렇다면 귀하의 경우 코드를 삽입하는 데 걸리는 시간이 act()이 될 것이라고 말했습니까? 어쨌든 당신의 보호 된 방법으로 전화 하시겠습니까 doAct()?

희망이 있습니다.

+0

act()는 doAct (또는)를 호출하지 않을 수도있는 꽤 많은 논리를 가지고 있습니다.) 조건에 따라. doAct()가 호출 될 때만 기능을 삽입하려고합니다. 이 경우 나는 좋은 프로그래밍 원칙을 크게 위반하는 act() 논리를 복제해야 할 것이다.그것이 보호된다는 사실은 서브 클래스가 그것을 오버라이드 할 수 있기 때문입니다. 이 경우 하위 클래스이므로 Decorator 패턴을 사용하여 많은 수의 AbstractActor 서브 클래스를 서브 클래 싱하지 않도록합니다. 이 라이브러리의 제작자는 내 의도를 염두에두고 doAct()를 만들었지 만 장식용으로 빌려주지 않았습니다. –

+0

"클래스 디자이너가 메서드를 보호하면 해당 메서드가 그대로 유지됩니다." 그건 사실이 아니야. 프레임 워크를 사용할 때와 같이 Jar 파일에 클래스가있는 경우 확장을 통해 동작을 변경하는 유일한 방법은 컴포지션이 필요한 런타임 확장이 필요한 경우와 공용 메서드가 필요하거나 위치를 지정해야하는 경우가 있습니다 같은 패키지에있는 수업. – CCC

0

나는 동일한 패키지 이름을 사용하는 것이 가장 좋은 답변이라고 생각하지만, 그 중 한 가지가 내 마음에 쏟아져 나와 의견을 말할 것이다.

doAct() 메소드 주위에 조언을 삽입하려면 Aspect Oriented Programming (예 : AOP, AspectJ)을 사용할 수 있어야합니다. Spring 환경에서 작업하면서 AOP 프로그래밍을 사용할 수있게되면서이 기능을 사용할 수 있습니다.

나는이 문제를 해결하기 위해 AOP를 아직 사용하지 않았다.

관련 문제