Компоновщик (шаблон проектирования)
Материал из Seo Wiki - Поисковая Оптимизация и Программирование
| Файл:LampFlowchart-ru.svg | Это незавершённая статья по информатике. Вы можете помочь проекту, исправив и дополнив её. |
Компоновщик (англ. Composite pattern) — шаблон проектирования, объединяет объекты в древовидную структуру для представления иерархии от частного к целому. Компоновщик позволяет клиентам обращаться к отдельным объектам и к группам объектов одинаково.
Содержание |
[править] Цель
Паттерн определяет иерархию классов, которые могут состоять из примитивных и сложных объектов, упрощает архитектуру клиента, делает процесс добавления новых видов объекта более простым.
[править] Описание
UML-диаграмма шаблона:
[править] Примеры реализации
[править] Пример на Java
import java.util.List; import java.util.ArrayList; /** "Component" */ interface Graphic { //Prints the graphic. public void print(); } /** "Composite" */ class CompositeGraphic implements Graphic { //Collection of child graphics. private List<Graphic> mChildGraphics = new ArrayList<Graphic>(); //Prints the graphic. public void print() { for (Graphic graphic : mChildGraphics) { graphic.print(); } } //Adds the graphic to the composition. public void add(Graphic graphic) { mChildGraphics.add(graphic); } //Removes the graphic from the composition. public void remove(Graphic graphic) { mChildGraphics.remove(graphic); } } /** "Leaf" */ class Ellipse implements Graphic { //Prints the graphic. public void print() { System.out.println("Ellipse"); } } /** Client */ public class Program { public static void main(String[] args) { //Initialize four ellipses Ellipse ellipse1 = new Ellipse(); Ellipse ellipse2 = new Ellipse(); Ellipse ellipse3 = new Ellipse(); Ellipse ellipse4 = new Ellipse(); //Initialize three composite graphics CompositeGraphic graphic = new CompositeGraphic(); CompositeGraphic graphic1 = new CompositeGraphic(); CompositeGraphic graphic2 = new CompositeGraphic(); //Composes the graphics graphic1.add(ellipse1); graphic1.add(ellipse2); graphic1.add(ellipse3); graphic2.add(ellipse4); graphic.add(graphic1); graphic.add(graphic2); //Prints the complete graphic (four times the string "Ellipse"). graphic.print(); } }
[править] Пример на C#
class MainApp { static void Main() { // Create a tree structure Component root = new Composite("root"); root.Add(new Leaf("Leaf A")); root.Add(new Leaf("Leaf B")); Component comp = new Composite("Composite X"); comp.Add(new Leaf("Leaf XA")); comp.Add(new Leaf("Leaf XB")); root.Add(comp); root.Add(new Leaf("Leaf C")); // Add and remove a leaf Leaf leaf = new Leaf("Leaf D"); root.Add(leaf); root.Remove(leaf); // Recursively display tree root.Display(1); // Wait for user Console.Read(); } } /// <summary> /// Component - компонент /// </summary> /// <li> /// <lu>объявляет интерфейс для компонуемых объектов;</lu> /// <lu>предоставляет подходящую реализацию операций по умолчанию, /// общую для всех классов;</lu> /// <lu>объявляет интерфейс для доступа к потомкам и управлению ими;</lu> /// <lu>определяет интерфейс доступа к родителю компонента в рекурсивной структуре /// и при необходимости реализует его. Описанная возможность необязательна;</lu> /// </li> abstract class Component { protected string name; // Constructor public Component(string name) { this.name = name; } public abstract void Add(Component c); public abstract void Remove(Component c); public abstract void Display(int depth); } /// <summary> /// Composite - составной объект /// </summary> /// <li> /// <lu>определяет поведеление компонентов, у которых есть потомки;</lu> /// <lu>хранит компоненты-потомоки;</lu> /// <lu>реализует относящиеся к управлению потомками операции и интерфейсе /// класса <see cref="Component"/></lu> /// </li> class Composite : Component { private ArrayList children = new ArrayList(); // Constructor public Composite(string name) : base(name) { } public override void Add(Component component) { children.Add(component); } public override void Remove(Component component) { children.Remove(component); } public override void Display(int depth) { Console.WriteLine(new String('-', depth) + name); // Recursively display child nodes foreach (Component component in children) { component.Display(depth + 2); } } } /// <summary> /// Leaf - лист /// </summary> /// <remarks> /// <li> /// <lu>представляет листовой узел композиции и не имеет потомков;</lu> /// <lu>определяет поведение примитивных объектов в композиции;</lu> /// </li> /// </remarks> class Leaf : Component { // Constructor public Leaf(string name) : base(name) { } public override void Add(Component c) { Console.WriteLine("Cannot add to a leaf"); } public override void Remove(Component c) { Console.WriteLine("Cannot remove from a leaf"); } public override void Display(int depth) { Console.WriteLine(new String('-', depth) + name); } }
[править] Пример на C++
#include <iostream> #include <list> #include <algorithm> #include <boost/shared_ptr.hpp> #include <boost/foreach.hpp> struct IText{ typedef boost::shared_ptr<IText> SPtr; virtual void draw() = 0; virtual void add(const SPtr&) { throw std::runtime_error("IText: Can't add to a leaf"); } virtual void remove(const SPtr&){ throw std::runtime_error("IText: Can't remove from a leaf"); } }; struct CompositeText: public IText{ void add(const SPtr& sptr){ _children.push_back(sptr); } void remove(const SPtr& sptr){ _children.remove(sptr); } void replace(const SPtr& oldValue, const SPtr& newValue){ std::replace(_children.begin(), _children.end(), oldValue, newValue); } virtual void draw(){ BOOST_FOREACH(SPtr& sptr, _children){ sptr->draw(); } } private: std::list<SPtr> _children; }; struct Letter: public IText{ Letter(char c):_c(c) {} virtual void draw(){ std::cout<<_c; } private: char _c; }; int main(){ CompositeText sentence; IText::SPtr space(new Letter(' ')); IText::SPtr excl(new Letter('!')); IText::SPtr comma(new Letter(',')); IText::SPtr newline(new Letter('\n')); IText::SPtr hello(new CompositeText); hello->add(IText::SPtr(new Letter('H'))); hello->add(IText::SPtr(new Letter('e'))); hello->add(IText::SPtr(new Letter('l'))); hello->add(IText::SPtr(new Letter('l'))); hello->add(IText::SPtr(new Letter('o'))); IText::SPtr world(new CompositeText); world->add(IText::SPtr(new Letter('W'))); world->add(IText::SPtr(new Letter('o'))); world->add(IText::SPtr(new Letter('r'))); world->add(IText::SPtr(new Letter('l'))); world->add(IText::SPtr(new Letter('d'))); sentence.add(hello); sentence.add(comma); sentence.add(space); sentence.add(world); sentence.add(excl); sentence.add(newline); sentence.draw(); // ptrints "Hello, World!\n" IText::SPtr hi(new CompositeText); hi->add(IText::SPtr(new Letter('H'))); hi->add(IText::SPtr(new Letter('i'))); sentence.replace(hello, hi); sentence.draw(); // ptrints "Hi, World!\n" sentence.remove(world); sentence.remove(space); sentence.remove(comma); sentence.draw(); // ptrints "Hi!\n" return 0; }
| структурные шаблоны проектирования |
|
адаптер | мост | компоновщик | декоратор | фасад | заместитель | приспособленец | Выделение частного класса данных |
cs:Composite de:Kompositum (Entwurfsmuster) en:Composite pattern es:Composite (patrón de diseño) fr:Objet composite it:Composite ja:Composite パターン ko:Composite 패턴 pl:Kompozyt (wzorzec projektowy) pt:Composite th:คอมโพสิตแพตเทิร์น vi:Composite pattern