Нужен ли образец декоратора конкретному классу? (а называть базовый класс из декоратора?) - PullRequest
0 голосов
/ 27 августа 2009

Это пример из: 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 # Design шаблоны 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. Во втором примере вообще нет конкретного компонента, кажется, что есть только компонент и декораторы, вот и все, я прав?Это все еще шаблон декоратора?Похоже, что это для меня.Просто хотел кое-что прояснить.

Спасибо

1 Ответ

0 голосов
/ 27 августа 2009
  1. Да, он вызывает базовый класс для выполнения базового метода Operation. Делая это, декоратор добавляет поведение.
  2. Да, это все еще декоратор

Вы можете написать различные реализации шаблона проектирования, важно выполнить намерение, в этом случае «Динамически прикрепить дополнительные обязанности к объекту», и вы напишите 2 из N способа сделать это в C #. *

НТН

...