2010-12-21 44 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

然後(Decorator模式下),將委託clone()回到原來mario實例。因此clone()將返回原始的mario而不是升級版本。

我意識到這一點,而不是克隆,我可以抓住紀念關升級馬里奧實例,並注入到這一點馬里奧的新實例,但感覺應該有一個簡單的解決方案...

有小費嗎?

回答

0

裝飾者增加了功能,所以你不會將所有事情都委託給原始的馬里奧。

是的,您可以將克隆委託給原始馬里奧,但是您的修飾器會使用它自己的大鬍子來更新鬍子屬性,然後返回更新後的克隆;

更新來解釋克隆: 裝飾模式的全部要點是隱藏包裝對象的新功能,所以包裝的對象不克隆裝飾的屬性。您調用頂級裝飾器的克隆方法。裝飾器重寫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

呵呵,最近我一直在做這麼多的C#代碼,我終於結束了我的判決;代替 。 =) – Stefan 2010-12-22 00:49:13