Компоновщик (шаблон проектирования)
Информатика | Это незавершённая статья по информатике. Вы можете помочь проекту, исправив и дополнив её. |
Компоновщик (англ. 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;
}
структурные шаблоны проектирования |
адаптер | мост | компоновщик | декоратор | фасад | заместитель | приспособленец | Выделение частного класса данных |
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 и ещё....