Украшать конкретный класс, плохая практика? - PullRequest
1 голос
/ 07 января 2020

Типичная uml-схема шаблона проектирования декоратора выглядит примерно так: https://www.dofactory.com/net/decorator-design-pattern

они показывают, что декоратор находится вокруг интерфейса.

Вопрос в том, действительно ли имеет значение, что это интерфейс или конкретный класс ?

Для начала декоратор не должен придираться к обернутому объекту поведение, это просто слой функциональности. Так что я не понимаю, как это рискованно, чем использовать интерфейс.

Обычно я бы хотел (хотел бы) украсить это так:

class Foo{
    public void doSmth(){
    }
}
class LoggedFoo extends Foo{
    private Foo wrappedFoo;
    public LoggedFoo(Foo foo){wrappedFoo = foo;}
    @override
    public void doSmth(){
        System.out.println("doSmth start");
        wrappedFoo.doSmth();
        System.out.println("doSmth end");
    }
}

Я не думаю, что мы должны смотреть прямо в глаза классовое наследие на первый взгляд, потому что «это опасно». Итак, интерфейс или конкретный класс, имеет ли значение здесь ?

Ответы [ 3 ]

2 голосов
/ 07 января 2020

Это важно, потому что вся идея Decorators состоит в том, чтобы добавить функциональность, не переходя к пути наследования реализации. Если вы в порядке с наследованием реализации и рискуете изменить существующее поведение объекта, тогда декоратор вообще не нужен.

Вся идея заключается в расширении функциональности, не нарушая существующее поведение, которое делает наследование реализации.

2 голосов
/ 07 января 2020

Расширение класса может привести к непреднамеренным побочным эффектам.

Если у Foo уже есть конструктор (или несколько), вы должны также реализовать его и вызвать суперкласс.

Кроме того, если у Foo есть закрытое состояние или побочные эффекты в конструкторе, теперь они выполняются дважды . Один раз для Foo, переданного в конструкторе, и один раз для LoggedFoo, который также является Foo.

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

0 голосов
/ 07 января 2020

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

...