2010-05-08 2 views
5

이것은 더 많은 디자인 질문입니다 ...장식하려는 클래스에서 상속받을 수없는 경우 Decorator 패턴을 어떻게 구현합니까?

1) 개체가 "봉인 된"것으로 표시되어 확장 할 수 없다는 의미입니다. 2) 또는 메소드를 오버라이드하고 싶지만 가상은 아닙니다.

그럼 어떻게 할 수 있습니까? 소스 코드 (예 : 타사 라이브러리)가 없으면 클래스 소스 코드를 변경할 수 없습니다.

답변

1

타사 클래스를 래핑하고 해당 클래스를 장식하는 고유 한 클래스를 만들 수 있습니다. 클래스는 래핑 된 클래스 구현을 사용합니다. 랩퍼 클래스는 어댑터의 역할을합니다.

1) 타사 코드에 봉인 클래스의 인스턴스를 전달하는 : 당신이 정말이 코드를 통해 얼마나 많은 컨트롤에 따라 취할 수있는 방법의

+1

그러나 유형이 다르므로 주제 클래스를 프록시 클래스로 대체 할 수 없습니다. – Ikke

+0

@ikke : 그건 사실이야. 따라서 나는 프록시 패턴을 말하지 않았다. – Ikaso

+1

은 프록시가 아닌 어댑터일까요? –

2

많은? 그렇다면 제 3자가 구체적인 객체 대신 인터페이스를 허용하도록기도하는 것 외에는 할 수있는 일이별로 없습니다.

봉인 된 클래스의 메서드를 가로 채기 위해 CLR에 후크를 작성하는 것이 가능합니다. 일부 비웃음 프레임 워크가 가상 메서드가 아닌 클래스와 봉인 된 클래스를 조롱하는 방식입니다. I 은 타사 코드가 특정 개체 구현에 대해 작성되었으며 타사 코드의 코드에서 구현을 스왑 아웃하는 것이 중요하지 않은 결과를 초래할 수 있으므로이 방법을 권장합니다.

2) 자신의 코드로 봉인 된 클래스를 사용하고 있습니까? 그렇다면 가제트 래퍼로 이동하십시오! 봉인 된 클래스와 동일한 공용 메서드를 사용하여 봉인되지 않은 클래스를 만들고 공용 메서드를 봉인 된 개체로 전달한 다음 필요에 따라 클래스의 기능을 재정의 할 수 있습니다.

3) 봉인 된 클래스에 대한 코드를 소유하고 있습니까? 그렇다면 클래스 정의를 찾고 'sealed'키워드를 두 번 클릭하여 강조 표시하고 필요에 따라 삭제 키를 누르십시오.) 대신 공개 된 메소드가있는 인터페이스에 대해 봉인 된 객체를 허용하는 메소드를 교체하십시오.

5

Decorator 패턴에는 상속이 필요하지 않습니다. 가장 간단한 경우는 장식하려는 객체가 인터페이스를 구현하는 경우입니다. 당신은 그냥 할 수있는 지금

[ IWindow ] 
[ + Draw() ] 
--------------- 
    | 
    +--- [ Window ] 
    | [ + Draw() ] 
    | 
    | 
    +--- [ DecoratedWindow ] 
     [ + Draw()  ] 
     ------------------- 
     | 
     +--- [ BorderDecorator ] 
     | 
     +--- [ VerticalScrollbarDecorator ] 
     | 
     +--- [ HorizontalScrollbarDecorator ] 

: 가능한 무엇인지

IWindow w = new BorderDecorator(
      new HorizontalScrollBarDecorator(
       new VerticalScrollBarDecorator(
       new Window(80, 24)))); 

// This is a window with a border and scrollbars, even though 
// the original Window class has no idea what those are. 
w.Draw(); 

구체적인 당신이하려는 클래스의 정확한 특성에 따라 달라집니다 그리고 당신의 장식은 단순히 동일한 인터페이스를 구현할 수 있습니다 장식하다.

+0

+1 인터페이스를 디자인 할 때. 클래스가 상속받을 수 없다면 이것은 특히 중요합니다! – Aaronaught

0

상속받을 수없고 원래 클래스가 데코레이터에 구현할 수있는 인터페이스를 구현하지 않으면 프록시 클래스 또는 어댑터를 사용해보아야한다고 생각합니다. 그리고 이것이 가능하지 않다면 항상 "대체 기술 리소스"가 있습니다. conversion operator을 정의하여 장식자를 원래의 것 (이 옵션은 좋지 않다고 생각하지만)으로 캐스팅 할 수 있습니다.

관련 문제