2011-01-30 5 views
1

Я работаю на примере давал Oreilly вдекоратор Помощь

using System; 
    using System.Drawing; 
    using System.Drawing.Drawing2D; 
    using System.Windows.Forms; 
    using System.Collections.Generic; 
    using Given; 

    // Decorator Pattern Example      Judith Bishop August 2007 
    // Draws a single photograph in a window of fixed size 
    // Has decorators that are BorderedPhotos and TaggedPhotos that can be composed and added 
    // in different combinations 

    namespace Given { 

    // The original Photo class 
    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); 
     } 
    } 
    } 

    class DecoratorPatternExample { 

    // This simple BorderedPhoto decorator adds a colored BorderedPhoto of fixed size 
    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); 
     } 
    } 

    // The TaggedPhoto decorator keeps track of the tag number which gives it 
    // a specific place to be written 

    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() { 
     // Application.Run acts as a simple client 
     Photo photo; 
     TaggedPhoto foodTaggedPhoto, colorTaggedPhoto, tag; 
     BorderedPhoto composition; 

     // Compose a photo with two TaggedPhotos and a blue BorderedPhoto 
     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()); 

     // Compose a photo with one TaggedPhoto and a yellow BorderedPhoto 
     photo = new Photo(); 
     tag = new TaggedPhoto (photo,"Jug"); 
     composition = new BorderedPhoto(tag, Color.Yellow); 
     Application.Run(composition); 
     Console.WriteLine(tag.ListTaggedPhotos()); 
    } 
    } 
/* Output 

TaggedPhotos are: Food Yellow                         
TaggedPhotos are: Food Yellow Jug 
*/ 

Следующая Упражнение является

Предположим, что класс фотография была написана с полкой, как равнина (не виртуальный) метод, и он не может быть изменено. Восстановите пример 2-2, чтобы он работал по этому ограничению

Как я могу это сделать?

Мой подход

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Drawing; 
using System.Windows.Forms; 
using GivenWihInterface; 


namespace GivenWihInterface 
{ 
    interface IPhoto 
    { 
     void Drawer(object sender, PaintEventArgs e); 
    } 

    class Photo : Form, IPhoto 
    { 
     Image image; 

     public Photo() 
     { 
      image = new Bitmap(@"c:\users\anishmarokey\documents\visual studio 2010\Projects\Design_Pattern_Decorator\DecoratorPattern_RealExample\Images\apple-6.jpg"); 
      this.Text = "Apple"; 
      this.Paint += new PaintEventHandler(Drawer); 
     } 
     public void Drawer(object sender, PaintEventArgs e) 
     { 
      e.Graphics.DrawImage(image, 20, 20); 
     } 
    } 

    class BorderPhoto : Form, IPhoto 
    { 
     IPhoto pho; 
     Color color; 

     public BorderPhoto(IPhoto p, Color c) 
     { 
      pho = p; 
      color = c; 
      this.Paint += new PaintEventHandler(Drawer); 
     } 

     public void Drawer(object sender, PaintEventArgs e) 
     { 
      pho.Drawer(sender, e); 
      e.Graphics.DrawRectangle(new Pen(color, 10), 25, 15, 215, 225); 
     } 
    } 
} 
namespace DecoratorPattern_RealExample 
{ 
    class DecoratorPatternWithInterface 
    { 
     static void Dispaly(GivenWihInterface.IPhoto p) 
     { 
      Application.Run((Form)p); 
     } 
     static void Main() 
     { 
      IPhoto component = new GivenWihInterface.Photo(); 
      Dispaly(component); 

      component = new GivenWihInterface.Photo(); 
      IPhoto p = new GivenWihInterface.BorderPhoto(component,Color.Red); 
      Application.Run((Form)p); 
     } 
    } 
} 

это правильный путь?

+0

Это вопрос дома? Вы сталкивались с какими-либо трудностями при его реализации? Пожалуйста, разместите свой подход. – WorldIsRound

+2

обновил вопрос с моим подходом – user595591

+0

удален «java» тег –

ответ

2

Да, это соответствующая реализация «декоратора». Единственное, на что я поставил бы вопрос: действительно ли вам нужно наследовать от Form или достаточно ли реализовать IPhoto. На что можно ответить только с большим контекстом.

Кроме того, жестко закодированные (размеры?) Значения выглядят так, что может быть лучший способ, если некоторые существующие значения доступны где-то.

Пример сам по себе необычен, но вам пришлось ввести интерфейс, который в значительной степени отличается от изменений, которые вы пытаетесь избежать; и тип обрабатывает событие на себе, что является плохой практикой. Я почти задаюсь вопросом, хотят ли они, чтобы вы подключались к конвейеру событий, но это не было бы действительно декоратором.

Я подозреваю, что они хотят, чтобы вы вводили код напротив формы, а не IPhoto, которую вы представили, что позволит вам украсить множество вещей. Но вам нужно будет иметь известный метод в форме для вызова, например Paint() - за исключением того, что это событие здесь, а не метод, так что имя будет отличаться. И снова мы могли зацепить событие, но это не классическое использование декоратора.

+0

не могли бы вы предоставить пример – user595591

+0

Of? В приведенном выше, не без лишнего контекста. Вопрос в том, как я пытался несколько раз сказать, неясно в намерении. –

+0

следующий вопрос. Каков наилучший способ изучения шаблонов проектирования и диаграмм uml? – user595591

Смежные вопросы