2010-12-21 5 views
0

데코레이터 패턴을 사용하여 clone() 메소드를 구현하는 가장 좋은 방법은 무엇입니까? 이 장식 시나리오에서 데코레이터 패턴을 사용하여 clone() 구현

:

var mario:Hero = new Mario();
mario = new HeroUpgrade(mario); //bigger moustache ;)
mario.clone(); //<--trying to grab a clone of the upgraded mario

다음 (데코레이터 패턴 다음) 원래 mario 인스턴스에 다시 clone()을 위임 할 것입니다. 따라서 clone()은 업그레이드 된 버전이 아닌 원래 mario을 반환합니다.

... 차라리 복제보다, 내가 업그레이드 된 마리오 인스턴스 떨어져 유품을 잡아 수 있으며, 마리오의 새로운 인스턴스로 그를 주입, 실현,하지만 간단한 해결책이 있어야처럼 느낌

어떤 팁?

답변

0

데코레이터는 기능을 추가하므로 모든 항목을 원래의 마리오에게 다시 위임하지 않습니다.

예, 원래 마리오에 복제를 위임 할 수 있지만 데코레이터는 더 큰 콧수염으로 콧수염 속성을 업데이트 한 다음 업데이트 된 복제본을 반환합니다.

복제 설명에 대한 업데이트 : 데코레이터 패턴의 전체적인 점은 래핑 된 오브젝트에서 새로운 기능을 숨기기 때문에 래핑 된 오브젝트는 데코 레이팅 된 특성을 복제하지 않습니다. 최상위 레벨 데코레이터의 clone 메소드를 호출합니다. 데코레이터는 Clone 메서드를 재정 의하여 고유 한 기능을 투명하게 추가합니다. 이 콘솔 애플리케이션

public class Mario : ICloneable 
    { 
     public Mario() 
     { 
      MoustacheSize = 1; 
     } 

     private double _moustacheSize; 
     public virtual double MoustacheSize 
     { 
      get { return _moustacheSize; } 
      internal set { _moustacheSize = value; } 
     } 

     public virtual object Clone() 
     { 
      var clone = new Mario(); 
      clone.MoustacheSize = this.MoustacheSize; 
      return clone; 
     } 
    } 

    public class HeroUpgradeDecorator : Mario 
    { 
     public HeroUpgradeDecorator(Mario mario) 
     { 
      _inner = mario; 
     } 

     private Mario _inner; 

     public override double MoustacheSize 
     { 
      get 
      { 
       return _inner.MoustacheSize * 1.2; // 20% increase in moustache size 
      } 
     } 

     public override object Clone() 
     { 
      var clone = new Mario(); 
      clone.MoustacheSize = this.MoustacheSize; 
      return clone; 
     } 
    } 

    static void Main(string[] args) 
    { 
     var mario = new Mario(); 
     Console.WriteLine("Mario, with moustache size: {0}", mario.MoustacheSize); 

     Console.WriteLine("Upgrading..."); 
     mario = new HeroUpgradeDecorator(mario); // variable mario now points to the decorator 
     Console.WriteLine("Mario, with moustache size: {0}", mario.MoustacheSize); 

     Console.WriteLine("Upgrading again..."); 
     mario = new HeroUpgradeDecorator(mario); // variable mario now points to the 2nd decorator 
     Console.WriteLine("Mario, with moustache size: {0}", mario.MoustacheSize); 

     Console.ReadLine(); 
    } 

출력된다 :

Mario, with moustache size: 1 
Upgrading... 
Mario, with moustache size: 1.2 
Upgrading again... 
Mario, with moustache size: 1.44 

이를 수행 할 수있는 장식을 복제 특성 많다는 대안 경우 :

 public override object Clone() 
     { 
      var clone = (Mario)_inner.Clone(); 
      clone.MoustacheSize = this.MoustacheSize; 
      return clone; 
     } 

데코레이터 클론 방식을 사용 원래 개체의 속성을 업데이트 한 다음 변경된 속성을 업데이트합니다. 그러나 최종 결과를 책임지는 것은 여전히 ​​장식가입니다.

+0

hehe, 최근에 C# 코딩을 많이 했어. 나는 내 문장을 끝냈다. 대신에 . =) – Stefan

+0

하지만 원래의 마리오의 복제본()이 장식 된 속성에 액세스하는 방법은 무엇입니까? – johnlindquist

+0

@johnlindquist 설명 할 답변이 업데이트되었습니다. – Stefan