C# 装饰图案帮助
我正在研究一个奥雷利的例子C# 装饰图案帮助,c#,design-patterns,C#,Design Patterns,我正在研究一个奥雷利的例子 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
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
*/
这是正确的方法吗?是的,这是一个合适的“装饰器”实现。我唯一想问的是,您是否真的需要从
表单继承,或者实现IPhoto
是否足够。这只能用更多的上下文来回答
此外,如果某些现有值在某处可用,硬编码(维度?)值看起来可能有更好的方法
不过,这个例子本身是不寻常的——您必须引入接口,这几乎是您试图避免的一个变化;类型本身处理事件,这是一种不好的做法。我几乎想知道他们是否想让你参与到活动管道中,但那并不是一个真正的装饰师
我怀疑他们想让你按照表单编码,而不是你介绍的IPhoto,它可以让你装饰很多东西。但是您需要在表单上有一个已知的方法来调用,例如Paint()-除非这里是一个事件,而不是一个方法,所以名称会有所不同。同样,我们可以将事件挂钩,但这不是装饰师的经典用法。这是一个家庭作业问题吗?在实施过程中,您是否遇到过任何困难?请发布你的方法。用我的方法更新了问题。你能提供一个例子吗?在上面,没有更多的上下文。正如我多次试图说的那样,这个问题的意图并不明确。还有一个问题。研究设计模式和uml图的最佳方法是什么?它们是非常不同的东西,但在任何地方。。。GOF将是一个良好的开端
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);
}
}
}