Компоновщик (шаблон проектирования)

Материал из Seo Wiki - Поисковая Оптимизация и Программирование
Перейти к навигацииПерейти к поиску

Компоновщик (англ. Composite pattern) — шаблон проектирования, объединяет объекты в древовидную структуру для представления иерархии от частного к целому. Компоновщик позволяет клиентам обращаться к отдельным объектам и к группам объектов одинаково.

Цель

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

Описание

UML-диаграмма шаблона:

Файл:Composite.gif

Примеры реализации

Пример на Java

<source lang=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();
   }

} </source>

Пример на C#

<source lang="csharp">

 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>

///

  • /// <lu>объявляет интерфейс для компонуемых объектов;</lu> /// <lu>предоставляет подходящую реализацию операций по умолчанию, /// общую для всех классов;</lu> /// <lu>объявляет интерфейс для доступа к потомкам и управлению ими;</lu> /// <lu>определяет интерфейс доступа к родителю компонента в рекурсивной структуре /// и при необходимости реализует его. Описанная возможность необязательна;</lu> ///
  • 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> ///

  • /// <lu>определяет поведеление компонентов, у которых есть потомки;</lu> /// <lu>хранит компоненты-потомоки;</lu> /// <lu>реализует относящиеся к управлению потомками операции и интерфейсе /// класса <see cref="Component"/></lu> ///
  • 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> ///

  • /// <lu>представляет листовой узел композиции и не имеет потомков;</lu> /// <lu>определяет поведение примитивных объектов в композиции;</lu> ///
  • /// </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); } } </source>

    Пример на C++

    <source lang="cpp">

    1. include <iostream>
    2. include <list>
    3. include <algorithm>
    4. include <boost/shared_ptr.hpp>
    5. 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; } </source>



    структурные шаблоны проектирования

    адаптер | мост | компоновщик | декоратор | фасад | заместитель | приспособленец | Выделение частного класса данных

    bg:Композиция (шаблон) 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

    Если вам нравится SbUP.com Сайт, вы можете поддержать его - BTC: bc1qppjcl3c2cyjazy6lepmrv3fh6ke9mxs7zpfky0 , TRC20 и ещё....