Pull to refresh

Comments 20

Отличный способ вместо масштабирования получить комбинаторный взрыв.

Шаблон декоратор вообще-то про другое.

идентификаторы доступа

Что такое идентификатор доступа? Впервые слышу такой термин

Во-первых, зачем нужна еще одна статья про паттерны проектирования?

Во-вторых, прежде чем задаваться вопросом "Давайте подумаем, как обернуть экземпляры класса ModelA или ModelB новой опцией", нужно определиться, зачем что-то оборачивать, и почему нельзя обойтись обычным контейнером.

В-третьих, для декоратора не нужен собственный базовый класс.

Так что прежде чем писать еще одну статью про паттерны проектирования, неплохо бы сначала, гм, освоить эти самые паттерны. Потом может внезапно оказаться, что писать уже ничего не надо.

Все паттерны делятся на категории, и перед их рассмотренеим, лучше начать изучение с самих паттернов, иначе ты не поймешь почему Декоратор является составным паттерном, а Фабрика порождающим. После изучения уже интуитивно будет понятно, почему какой-либо паттерн относиться к той или иной категории.

Отдельный вопрос - а зачем рассматривать категории паттернов, и пытаться понять, почему один паттерн - "составной", а другой - "порождающий".

почему Декоратор является составным паттерном

Я сначала вообще не понял, что такое "составной паттерн", потому что в русская языка более как-то общепринято говорить "структурный" :)

Декораторы всегда делают к интерфейсам а не к абстрактным классам, декоратор реализует интерфейс, который декорирует, как раз это позволяет декорировать не только исходный класс/интерфейс но и его декораторы, декораторы декораторов и т.п. - в этом и суть паттерна.

А вот за это:

public Car _car;

вас вообще когда-нибудь покалечат.

Ну, есть языки, где нету интерфейсов, а декораторы иметь хочется... Но это явно не тот случай.

Может быть человек пришёл с питона и тут осенило, что на типизации можно делать прикольные вещи.

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

По примерам кода выше уже проехались. Добавлю, что тема очень избитая, и сказать что-то новое (а иначе зачем писать статью, особенно на Хабр) достаточно сложно. Плюс, декоратор - сам по себе популярный и многим известный паттерн, и с его вариациями в DI, в сторонних библиотеках типа MediatR, или просто работая с middleware pipeline - сталкивались многие. Поэтому, опытному разработчику эта статья не нужна, а новичку я бы рекомендовал прочитать любой популярный гайд/курс/книгу по паттернам. Если очень хочется именно C# и на русском языке - есть прекрасная книга Сергея Теплякова. Да хотя бы статья на википедии.

Car car = new ModelA();
car = new WheelDisk..
car = new AutomaticParkingSystem..

Можно координаты автора? Я ему цветы на могилку принесу. Или, если коллеги не убили и ещё живой - торт.
Я такой дичи за 20 лет работы не видел. Даже не знаю, плакать хочется, но и настолько оригинально!

Каждый день делаю системы из говен и палок. Этот пример идеально демонстрирует как можно сделать Candy candy = new Shit();

Просто никто фишку не понял

Наоборот надо, тип ссылки - какаха, а в рантайме фактически получаем конфетку.)

Это больше смахивает на композицию, но уж никак не на декортатор

Но на ерунду гораздо сильнее.

Сильно упрощённо переписал, теперь видно наглядно, "простым языком без лишних слов"..
    public interface ICar
    {
        string GetDescription();
        decimal Price();
    }

    
    public class ModelA : ICar
    {
        public string GetDescription()
        {
            return "ModelA";
        }

        public decimal Price()
        {
            return 40_000.034m;
        }
    }


    
    public abstract class CarDecorator : ICar
    {
        protected ICar _car;

        public CarDecorator(ICar car)
        {
            _car = car;
        }

        public virtual string GetDescription()
        {
            return _car.GetDescription();
        }

        public virtual decimal Price()
        {
            return _car.Price();
        }
    }


    
    public class AutomaticParkingSystem : CarDecorator
    {
        public AutomaticParkingSystem(ICar car) : base(car)
        {
        }

        public override string GetDescription()
        {
            return $"{_car.GetDescription()}, new automatic parking system";
        }

        public override decimal Price()
        {
            return _car.Price() + 2_300.4m;
        }
    }

Видно что? Как реализовывать интерфейсы и наследование в C#? И какое отношение это имеет к декоратору?

В порядке ремарки для лучшего понимания паттернов:

  • Классы (точнее, объекты этих классов) - это про наличие состояния

  • Объекты получаются композицией примитивных значений или других объектов как естественное описание в терминах перечисления (у кота 4 лапы, хвост, голова и т.п., в зависимости от того, что является важным в задаче)

  • Наследование с одной стороны выражает свойство уточнения при реализации потомков, и общность при движении вверх (потомок есть предок а-ля кот есть животное)

  • Интерфейсы - это декларация возможностей/умений (кот умеет ходить и мяукать)

Если брать конкретно паттерн декоратор, то он позволяет внедрить новое поведение в уже существующее поведение путём декорирования умений.

Может кто-нибудь запилит как должен выглядеть декоратор для dotnet?

Sign up to leave a comment.

Articles