2009-08-27 33 views
0

這是一個例子:dofactory裝飾者模式是否需要具體的類? (並從裝飾調用基類的?)

我重新格式化有點爲更好地適應(壓縮):

namespace DoFactory.GangOfFour.Decorator.Structural{ 
class MainApp{ 

     static void Main(){ 
      ConcreteComponent c = new ConcreteComponent(); 
      ConcreteDecoratorA d1 = new ConcreteDecoratorA();  
      ConcreteDecoratorB d2 = new ConcreteDecoratorB(); 

      d1.SetComponent(c);  
      d2.SetComponent(d1); 
      d2.Operation(); 
     }  
     } 

     abstract class Component{  
     public abstract void Operation();  
     } 

     class ConcreteComponent : Component{  
     public override void Operation(){  
      Console.WriteLine("ConcreteComponent.Operation()");  
     }  
     }  

     abstract class Decorator : Component{  
     protected Component component;  

     public void SetComponent(Component component){  
      this.component = component; 
     }  

     public override void Operation(){  
      if (component != null){  
      component.Operation();  
      }  
     }  
     }  

     class ConcreteDecoratorA : Decorator{  
     public override void Operation(){  
      ****base.Operation();****  
      Console.WriteLine("ConcreteDecoratorA.Operation()");  
     }  
     } 

     class ConcreteDecoratorB : Decorator{  
     public override void Operation(){  
      **base.Operation();**  
      AddedBehavior();  
      Console.WriteLine("ConcreteDecoratorB.Operation()"); 
     }  
     void AddedBehavior(){}  
     }  
    } 

現在有了這個一個比較(這是從C#設計模式3.0 - O'Reilly)的:

namespace Given { 

     public class Photo : Form{ 
     Image image; 
     public Photo() { 
     image = new Bitmap("jug.jpg"); 
     this.Text = "Lemonade"; 
     this.Paint += new PaintEventHandler(Drawer); 
     } 

     public virtual void Drawer(Object source, PaintEventArgs e) { 
     e.Graphics.DrawImage(image,30,20); 
     } 

     private void InitializeComponent(){ 
      this.SuspendLayout(); 
     this.ClientSize = new System.Drawing.Size(283, 250); 
      this.Name = "Photo"; 
      this.ResumeLayout(false); 
     } 
    } 
    } 

    class DecoratorPatternExample { 

    class BorderedPhoto : Photo { 
     Photo photo; 
     Color color; 

     public BorderedPhoto (Photo p, Color c) { 
     photo = p; 
     color=c; 
     } 

     public override void Drawer(Object source, PaintEventArgs e) { 
     photo.Drawer(source, e); 
     e.Graphics.DrawRectangle(new Pen(color, 10),25,15,215,225); 
     } 
    } 

    class TaggedPhoto : Photo { 
     Photo photo; 
     string tag; 
     int number; 
     static int count; 
     List <string> tags = new List <string>(); 

     public TaggedPhoto(Photo p, string t) { 
      photo = p; 
      tag = t; 
      tags.Add(t); 
      number = ++count; 
     } 

     public override void Drawer(Object source, PaintEventArgs e) { 
      photo.Drawer(source,e); 
      e.Graphics.DrawString(tag, 
      new Font("Arial", 16), 
      new SolidBrush(Color.Black), 
      new PointF(80,100+number*20)); 
     } 

     public string ListTaggedPhotos() { 
      string s = "Tags are: "; 
      foreach (string t in tags) s +=t+" "; 
      return s; 
     } 
    } 

    static void Main() {  
     Photo photo; 
     TaggedPhoto foodTaggedPhoto, colorTaggedPhoto, tag; 
     BorderedPhoto composition; 

     photo = new Photo(); 
     Application.Run(photo); 
     foodTaggedPhoto = new TaggedPhoto (photo,"Food"); 
     colorTaggedPhoto = new TaggedPhoto (foodTaggedPhoto,"Yellow"); 
     composition = new BorderedPhoto(colorTaggedPhoto, Color.Blue); 
     Application.Run(composition); 
     Console.WriteLine(colorTaggedPhoto.ListTaggedPhotos()); 

     photo = new Photo(); 
     tag = new TaggedPhoto (photo,"Jug"); 
     composition = new BorderedPhoto(tag, Color.Yellow); 
     Application.Run(composition); 
     Console.WriteLine(tag.ListTaggedPhotos()); 
    } 
    } 

幾個問題, 容易之一: 1.該混凝土裝飾(如在第一個例子)必須調用基上課嗎? 2.在第二個例子中,根本沒有具體的組件,似乎只有一個組件和裝飾器,就是這樣,對嗎?它仍然是裝飾者模式?這似乎是對我來說。只是想澄清一些事情。

感謝

回答

0
  1. 是的,它調用基類來執行基本操作方法。做這個裝飾器會增加一個行爲。
  2. 是的,它仍然是一個裝飾

您可以編寫各種實現設計模式的,重要的是滿足的意圖,在這種情況下,「附加額外的職責動態對象」和你寫2 N方式在C#中執行此操作。

HTH

+0

我的唯一的其他問題是,其他的例子怎麼沒有調用基類? – ra170 2009-08-27 18:19:16

+0

它調用照片實例的Drawer方法,photo是在構造函數中傳遞的基本實例,所以它是相同的。 – ema 2009-08-29 15:30:11