dev*_*ium 7 c# design-patterns decorator
我试图将装饰器设计模式应用于以下情况:
我有3种不同的形式:绿色,黄色,红色.
现在,每个表单都可以具有不同的属性集.他们可以禁用最小化框,禁用最大化框,它们可以始终位于顶部.
我尝试通过以下方式对其进行建模:
Form <---------------------------------------FormDecorator
/\ /\
|---------|-----------| |----------------------|-----------------|
GreenForm YellowForm RedForm MinimizeButtonDisabled MaximizedButtonDisabled AlwaysOnTop
Run Code Online (Sandbox Code Playgroud)
这是我的GreenForm代码:
public class GreenForm : Form {
public GreenForm() {
this.BackColor = Color.GreenYellow;
}
public override sealed Color BackColor {
get { return base.BackColor; }
set { base.BackColor = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
FormDecorator:
public abstract class FormDecorator : Form {
private Form _decoratorForm;
protected FormDecorator(Form decoratorForm) {
this._decoratorForm = decoratorForm;
}
}
Run Code Online (Sandbox Code Playgroud)
最后是NoMaximizeDecorator:
public class NoMaximizeDecorator : FormDecorator
{
public NoMaximizeDecorator(Form decoratorForm) : base(decoratorForm) {
this.MaximizeBox = false;
}
}
Run Code Online (Sandbox Code Playgroud)
所以这是运行代码:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(CreateForm());
}
static Form CreateForm() {
Form form = new GreenForm();
form = new NoMaximizeDecorator(form);
form = new NoMinimizeDecorator(form);
return form;
}
Run Code Online (Sandbox Code Playgroud)
问题是我得到的表格不是绿色的,仍然允许我最大化它.它只考虑了NoMinimizeDecorator表单.我理解为什么会发生这种情况,但我无法理解如何使用此模式进行此操作.
我知道可能有更好的方法来实现我想要的.我将这个例子作为尝试将Decorator模式应用于某事.也许这不是我可以使用的最佳模式(如果有的话),这种情况.是否还有其他模式比Decorator更适合实现这一目标?在尝试实现Decorator模式时,我做错了吗?
谢谢
这里的问题是你实际上并没有实现装饰器模式.为了正确实现模式,您需要子类Form来创建装饰器,然后拦截装饰器上的所有操作并将它们转发到您的私有Form实例.除此之外,除了在FormDecorator构造函数中分配引用之外,您再也不会使用该私有Form实例.最终的结果是你创建一个GreenForm,然后将它包装在一个NoMaximizeDecorator,然后你将其包装在一个NoMinimizeDecorator.但是因为您从未将针对NoMinimizeDecorator包装Form实例的操作转发到包装实例,所以只有NoMinimizeDecorator实例实际将任何行为应用于所使用的实例.这符合您在运行代码时观察到的内容:带有禁用的最小化按钮的标准窗口.
Form在C#中创建装饰器是一个非常糟糕的例子,因为它的大多数属性和方法都是非虚拟的,这意味着如果你通过Form引用访问装饰的表单,你就无法拦截基类的属性 - 你可以'有效地"包裹" Form.
编辑
它发生,我认为声明"形式是用C#创建装饰一个非常糟糕的榜样"真的乞求什么的问题就是一个很好的例子.通常,您将使用装饰器模式来提供自定义接口实现,而无需从头开始实现整个实现.一个非常常见的例子是泛型集合.大多数想要列表功能的东西都不依赖于,例如List<String>,而是依赖于IList<String>.因此,如果您想要一个不接受短于5个字符的字符串的自定义集合,您将使用类似以下内容:
public class MinLengthList : IList<String>
{
private IList<string> _list;
private int _minLength;
public MinLengthList(int min_length, IList<String> inner_list)
{
_list = inner_list;
_minLength = min_length;
}
protected virtual void ValidateLength(String item)
{
if (item.Length < _minLength)
throw new ArgumentException("Item is too short");
}
#region IList<string> Members
public int IndexOf(string item)
{
return _list.IndexOf(item);
}
public void Insert(int index, string item)
{
ValidateLength(item);
_list.Insert(index, item);
}
public void RemoveAt(int index)
{
_list.RemoveAt(index);
}
public string this[int index]
{
get
{
return _list[index];
}
set
{
ValidateLength(value);
_list[index] = value;
}
}
#endregion
#region ICollection<string> Members
public void Add(string item)
{
ValidateLength(item);
_list.Add(item);
}
public void Clear()
{
_list.Clear();
}
public bool Contains(string item)
{
return _list.Contains(item);
}
public void CopyTo(string[] array, int arrayIndex)
{
_list.CopyTo(array, arrayIndex);
}
public int Count
{
get { return _list.Count; }
}
public bool IsReadOnly
{
get { return _list.IsReadOnly; }
}
public bool Remove(string item)
{
return _list.Remove(item);
}
#endregion
#region IEnumerable<string> Members
public IEnumerator<string> GetEnumerator()
{
return _list.GetEnumerator();
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return ((IEnumerable)_list).GetEnumerator();
}
#endregion
}
public class Program
{
static void Main()
{
IList<String> custom_list = new MinLengthList(5, new List<String>());
custom_list.Add("hi");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1347 次 |
| 最近记录: |