装饰图案& c#中的扩展方法

时间:2011-02-03 15:33:06

标签: c# design-patterns

在首先描述我的问题之前,我想定义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);
    }
}

在上面的代码中,我在不修改现有代码的情况下扩展接口,这两种方法可用于派生类。所以我的问题是:扩展方法是否取代了装饰模式?

5 个答案:

答案 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接口