在首先描述我的问题之前,我想定义Decorator和Extension方法的定义 的装饰
动态地将附加职责附加到对象。装饰器为子类化提供了灵活的替代方法,以扩展功能
扩展方法
扩展方法使您可以向现有类型“添加”方法,而无需创建新的派生类型,重新编译或以其他方式修改原始类型
我在c#
中有以下代码段public interface IMyInterface
{
void Print();
}
public static class Extension
{
public static void PrintInt(this IMyInterface myInterface, int i)
{
Console.WriteLine
("Extension.PrintInt(this IMyInterface myInterface, int i)");
}
public static void PrintString(this IMyInterface myInterface, string s)
{
Console.WriteLine
("Extension.PrintString(this IMyInterface myInterface, string s)");
}
}
public class Imp : IMyInterface
{
#region IMyInterface Members
public void Print()
{
Console.WriteLine("Imp");
}
#endregion
}
class Program
{
static void Main(string[] args)
{
Imp obj = new Imp();
obj.Print();
obj.PrintInt(10);
}
}
在上面的代码中,我在不修改现有代码的情况下扩展接口,这两种方法可用于派生类。所以我的问题是:扩展方法是否取代了装饰模式?
答案 0 :(得分:18)
扩展方法实际上只是用于调用静态方法的语法糖。
虽然使用装饰器实际上可以改变装饰类的行为,但扩展方法只能改变属性或调用类的方法,就像“普通”静态方法一样。
装饰器模式实际上被定义为使用包装器来改变行为,扩展方法显然不会这样做。
答案 1 :(得分:15)
你错过了装饰图案的动态部分。扩展方法是在编译时定义的静态动画,可以使用或不使用......但不能在运行时修改/交换。
答案 2 :(得分:5)
扩展方法不是装饰器模式的替代品。扩展方法用于为现有类型提供功能,而无需创建派生类型。
这与传统的实现到装饰器模式不同。装饰器模式允许您在运行时动态地为对象提供多个行为,而无需为这些行为的每个组合创建新的子类。
答案 3 :(得分:4)
扩展方法是Decorator模式还是Visitor模式?阅读之后,我会说它更类似于访客。
引用伟大的维基百科,从未出现错误的小便:P
在面向对象的编程和软件工程中,访问者 设计模式是一种将算法与对象分离的方法 它运作的结构。这种分离的实际结果是 能够在没有的情况下向现有对象结构添加新操作 修改这些结构。这是一种轻松遵循的方法 开放/封闭原则。实质上,访问者允许添加新的 一系列类的虚函数,无需修改类 他们自己;相反,一个人创建一个实现所有的访问者类 虚函数的适当特化。该 visitor将实例引用作为输入,并实现目标 通过双重派遣。
答案 4 :(得分:0)
Erich Gamma(GoF)的解释似乎是最好的...... http://www.mif.vu.lt/~plukas/resources/Extension%20Objects/ExtensionObjectsPattern%20Gamma96.pdf
基本上说明
a)将不同客户端(现在和将来)需要的所有操作和状态组合到单个界面中会导致界面膨胀
b)期望的操作(已知和未知)可以分类为组件。可以定义一个(或多个)组件接口(扩展接口)。这些可能是也可能不是由对象(当前和未来)实现的。
c)希望使用此扩展接口的客户端可以查询组件是否支持它
d)最后,这个扩展接口有一个公共基类(ComponentExtension),它具有最小的接口来管理扩展本身(检查扩展是否存在,通知扩展它将要删除)
在以下时间使用:
1当您现有的课程可能需要其他和无法预料的界面(即新的,当前未知的行为模式)时。
2当代表关键抽象的类为不同的客户扮演不同的(不可预见的和开放式的)角色时。
3您希望在不进行子分类的情况下进行扩展
类似于以下模式
访问者,需要稳定的类层次结构&引入依赖循环
装饰器,其中使用更透明,界面狭窄,现有操作应该增加
适配器,支持EXISTING接口