2. UML-диаграмма паттерна «Декоратор»
Другими словами, нам нужно добавлять обязан-
ности к классу динамически, то есть нам нужно в run-
time определять, какая функциональность нам нужна
от класса. Если у нас есть обращение от клиента к сер-
веру, и нам нужно добавить дополнительную функцио-
нальность. Например, клиент хочет то кэширование, то
логирование, то аутентификацию, то что-то из этого од-
новременно и т. д. Классическое решение написать от-
дельный класс для сервера с кэшированием и т. д. Так
же написать класс для сервера с и логированием, и кэ-
шированием и т. д. Таким образом, чем больше требо-
ваний, тем больше классов нужно написать, количество
которых определяется комбинаторной комбинацией. Это
не совсем удобно.
«Декоратор» предлагает: вызывать сервер через его
интерфейс. Для реализации функциональности создать
класс-наследник (по сути адаптер) этого интерфейса, ко-
торый, выполняя свою функциональность (например, ло-
гирование) вызывает методы сервера, но через интерфейс
сервера, то есть свой родительский интерфейс, для этого
в конструкторе наш класс принимает instance, то есть со-
держит в конструкторе поле ServerInterface.
Аналогично для класса, осуществляющего кэширо-
вание, аутентификацию и т. д. Теперь клиент, который сам
решает, какая функциональность ему нужна, может про-
инстанциировать один адаптер, передав ему в конструк-
торе другой адаптер. И такую цепочку можно осущест-
влять до бесконечности. Важно, что в зависимости от того,
кого и кому мы передаем, код будет сначала кэшировать, а
потом логировать, или наоборот.
Если мы, к примеру, пишем класс Report, который
будет выводить одну строчку, но при этом каждый раз её
нужно будет обрамить по-новому, очень удобно использо-
вать «Декоратор». Или создаем окошко, у которого может
быть или горизонтальный скролл-бар, или вертикальный
скролл-бар, или вообще никакого.
К основным преимуществам паттерна «Декоратор» от-
носят:
— большая гибкость, чем у статического наследования:
можно добавлять и удалять обязанности во время выпол-
нения программы в то время, как при использовании на-
следования надо было бы создавать новый класс для ка-
ждой дополнительной обязанности;
— данный паттерн позволяет избежать перегру-
женных методами классов на верхних слоях уровня ие-
рархии — новые обязанности можно добавлять по мере
необходимости.
К недостаткам данного паттерна относят то, что «Де-
коратор» и его «Компонент» не идентичны, и, кроме
того, получается, что система состоит из большого числа
мелких объектов, которые похожи друг на друга и разли-
чаются только способом взаимосвязи, а не классом и не
значениями своих внутренних переменных. Такая система
сложна в изучении и отладке.
Do'stlaringiz bilan baham: |