Шаблон Decorator и методы расширения в c # - PullRequest
17 голосов
/ 03 февраля 2011

Прежде чем приступить к описанию моей проблемы, я хотел бы определить определения метода 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 ]

18 голосов
/ 03 февраля 2011

Метод расширения на самом деле является просто синтаксическим сахаром для вызова статического метода.

В то время как с помощью декоратора вы действительно можете изменить поведение вашего декорированного класса, метод расширения может изменять только свойства или вызывать методы вашего класса, точно так же, как «обычный» статический метод.

Шаблон декоратора фактически определяется как использование оболочки для изменения поведения, чего явно не имеет метод расширения.

15 голосов
/ 03 февраля 2011

- вам не хватает динамической части шаблона декоратора. Методы расширения - это статические звери, определенные во время компиляции, которые можно использовать или нет ... но не изменять или обменивать во время выполнения.

5 голосов
/ 03 февраля 2011

Методы расширения не заменяют шаблон декоратора. Методы расширения работают для обеспечения функциональности существующего типа без необходимости создания производного типа.

Это отличается от традиционной реализации для шаблона декоратора. Шаблон декоратора позволяет динамически предоставлять несколько вариантов поведения для объекта во время выполнения без необходимости создавать новый подкласс для каждой комбинации этих вариантов поведения.

4 голосов
/ 04 августа 2011

Метод расширения: шаблон Decorator или шаблон Visitor? После прочтения я бы сказал, что это больше похоже на Посетителя.

Цитируя величие википедии, педию, в которой никогда не бывает ошибок: P

В объектно-ориентированном программировании и разработке программного обеспечения посетитель шаблон проектирования - это способ отделения алгоритма от объекта структура, на которой он работает. Практическим результатом этого разделения является возможность добавлять новые операции в существующие структуры объектов без модифицируя эти структуры. Это один из способов легко следовать открытый / закрытый принцип. По сути, посетитель позволяет добавлять новые виртуальные функции для семейства классов без изменения классов самих себя; вместо этого создается класс посетителя, который реализует все соответствующих специализаций виртуальной функции. посетитель принимает ссылку на экземпляр в качестве входных данных и реализует цель через двойную отправку.

0 голосов
/ 09 июля 2017

Это объяснение Эриха Гаммы (GoF) кажется лучшим ... http://www.mif.vu.lt/~plukas/resources/Extension%20Objects/ExtensionObjectsPattern%20Gamma96.pdf

По сути, заявив, что

a) Объединение всех операций и состояния, необходимого для разных клиентов (настоящих и будущих) в единый интерфейс, приводит к раздутому интерфейсу

b) Желаемые операции (известные и неизвестные) можно разделить на компоненты. Из которого можно определить один (или более) компонентный интерфейс (расширенные интерфейсы). Они могут или не могут быть реализованы объектами (текущими и будущими). ​​

c) Клиенты, которые хотят использовать этот расширенный интерфейс, могут запросить, поддерживает ли его компонент

d) Наконец, этот расширенный интерфейс имеет общий базовый класс (ComponentExtension) с минимальным интерфейсом для управления самим расширением (проверка, существует ли расширение, информирование расширения о том, что оно собирается удалить)

Используется, когда:

1 Когда ваши существующие классы могут потребовать дополнительных и непредвиденных интерфейсов (то есть новых, в настоящее время неизвестных моделей поведения).

2 Когда класс, представляющий абстракцию ключа, играет разные (непредвиденные и открытые) роли для разных клиентов.

3 Вы хотите расширить без подклассов

Это похоже на следующие шаблоны

Посетитель , которому требуется стабильная иерархия классов и вводит цикл зависимостей

Декоратор , где использование более прозрачно, интерфейс узок и существующие операции должны быть расширены

Адаптер , который поддерживает СУЩЕСТВУЮЩИЕ интерфейсы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...