Шаблон Медиатор в JavaScript



Книга Шаблон Медиатор в JavaScript

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


Главная задача компоновщика  —  объединение множества объектов в единую древовидную структуру. В этом случае иерархия формируется по принципу от частного к целому.


Суть в том, что каждый объект коллекции  —  это часть общей композиции. Композиция, в свою очередь, является коллекцией ее частей.


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



Теперь, когда у нас есть более четкое представление принципа отношения между частным и целым, давайте вернемся к компоновщику. Мы определили, что его цель в структурировании объектов в дерево согласно этому принципу. 


Следовательно, мы получаем шаблон проектирования, в котором каждый элемент коллекции может также присоединять коллекцию, выстраивая глубокие структуры.


Внутреннее строение


Каждый узел в дереве разделяет общий набор свойств и методов, позволяющих ему поддерживать отдельные объекты, взаимодействуя с ними так же, как с коллекциями объектов. 


Такой интерфейс предполагает построение рекурсивных алгоритмов, перебирающих каждый объект в коллекции композита.


Где применяется этот шаблон?


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


Файлы (для удобства содержимое директории можно считать элементами) являются листьями/узлами (частями) внутри этого композита (директории).


Созданная поддиректория в директории аналогично является листом или узлом, включающим в себя другие элементы вроде видео, изображений и прочего. В то же время и директории, и поддиректории являются композитами, поскольку представляют собой коллекции частей: объектов, файлов и тому подобного. 


React или Vue широко применяют этот шаблон для построения надежных и переиспользуемых интерфейсов. Все элементы веб-страниц, которые вы видите  —  это компоненты. 


Каждый компонент  —  это лист древа и он может объединять множество компонентов, образуя другой лист. При этом образуется композит, который по-прежнему остается листом дерева.


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


Зачем же нам нужен этот шаблон?


Он дает возможность обращаться к объекту, как к композитному объекту. Это оказывается возможным благодаря общему интерфейсу. 


Исходя из этого свойства, вы можете многократно использовать объекты, не опасаясь столкнуться с их несовместимостью с другими. 


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


Примеры


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


Нам предстоит работать с классом Document, который будет иметь свойство signature со значением по умолчанию false. Если доктор подпишет документ, то это значение должно измениться на его подпись.


Мы также определяем в этом классе метод sign, осуществляющий эту функцию. Так будет выглядеть Document:



Теперь, применив компоновщик, мы включим те же методы, которые определены в Document.



Теперь становится очевидна изящность шаблона. Обратите внимание на два последних сниппета кода:



Отлично! Похоже мы на верном пути, о чем можно судить по соответствию текущей и предыдущей диаграмм:



Итак, наше дерево содержит два узла — Document и DocumentComposite. Оба они разделяют один и тот же интерфейс, и, следовательно, действуют как части единого композитного дерева. 


Здесь следует отметить, что лист/узел древа, не являющийся композитом (Document), не продолжит разветвления, т.к. не является коллекцией объектов. 


Тем не менее составной узел содержит коллекцию частей (в нашем случае items). Запомните также, что Document и DocumentComposite разделяют интерфейс, а значит разделяют и метод sign.


Так в чем же здесь сила?


Несмотря на то, что DocumentComposite разделяет единый интерфейс, выполняя при этом метод sign, аналогично Document, он воплощает в себе более эффективный подход, достигая при этом той же конечной цели. 


Поэтому вместо:



мы можем сделать код эффективнее с помощью компоновщика:



При таком подходе нам потребуется лишь единожды выполнить sign после добавления всех нужных документов, и он подпишет все документы.


Убедиться в этом мы можем, взглянув на вывод console.log(forms):



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


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


forms.add(pr2Form) // Документ
forms.add(w2Form) // Документ

наша диаграмма превратилась в:



Имея две добавленные формы, она отлично согласуется с нашей изначальной диаграммой:



Тем не менее наше дерево прекращает свой рост: последний его узел образовал только два листа, что не совсем соответствует приведенной выше диаграмме. Если бы вместо этого мы сделали форму w2form композитом:



тогда бы наше дерево продолжило развитие:



В итоге мы бы достигли той же цели подписания всех необходимых документов:



В этом и состоит польза компоновщика.


Заключение


Надеюсь, что эта информация оказалось для вас полезной.


442   0  

Comments

    Ничего не найдено.