Композиција или Састав (енгл. -{Composite}-) је објектно-оријентисани пројектни узорак. Припада категорији објектних узорака структуре. Компонује објекте у структуру стабла (хијерархија целина-део) и омогућава клијентима да униформно третирају индивидуалне објекте и њихове композиције. То се постиже тиме што се јасно дефинишу делови, док се целине (састави) предастављају као делови, али имају улогу контејнера тих делова.

Честе употребе Састав има велику примену када је потребно представљати хијерархије целина-део, што се постиже формирањем структуре у облику стабла. Посебно је користан када је потребно да корисници игноришу разлике између целина и делова, односно да их третирају униформно, чиме се корисничке класе подједностављују и олакшавају измене, тестирања и надоградње.

Учесници Постоје четири учесника за овај пројектни узорак.

Компонента Декларише заједничко понашање за све чворове објектног стабла. То значи да декларише заједнички интерфејс, али могуће је декларисати или имплементирати и приступ деци, као и родитељима, ако их компонента има.

Лист Имплементира понашање компоненте и представља примитиван објекат у композицији. Он је заправо лист објектног стабла што значи да нема децу.

Састав (Композиција) Представља објекат који имплементира онај део интерфејса за компоненте, који је везан за децу, јер се не ради о листу. Садржи децу компоненте, што значи да је могуће и да један састав буде дете другог састава.

Корисник Преко интерфејса компоненте, манипулише објектима стабла.

Дијаграм класа 600px|мини|Дијаграм класа пројектног узорка Композиција, као и пример објектног стабла које се може формирати. Дијаграм класа и пример објектног стабла за пројектни узорак композиција се налази на слици десно. Приказан је преко Обједињеног језика за моделирање.

Предности и мане Као што је већ речено, коришћење овог пројектног узорка подједностављује класе корисника, и омогућава лако додавање нових компонената што укључује и нове саставе, не само чворове. Због тога је могућа динамична изградња и мењање комплексних структура у време превођења. Ипак, могући проблем са саставом јесте управо у компоненти - теже је онемогућити додавање одређених компонената стаблу, које не желимо да видимо у њему. Такође, један од могућих проблема делимично везан за претходни јесте везан за појаву у имплементацији да се може доћи до облика Component.addComponent() када је Component заправо лист, што представља грешку, јер не желимо листу да додајемо децу.

Имплементација Приликом имплементације овог пројектног узорка, треба водити рачуна многим стварима, поготову оних који се тичу стабла као таквог. Треба имплементирати операције везане за децу или, опционо и родитеље, али водити рачуна приликом случајева када се одређене компоненте могу делити између других компонената. Такође, треба тежити ка максималном интерфејсу за компоненту - пожељно је да клијент буде растерећен тога да ли користи састав или лист. Због тога треба што више операција декларисати у интерфејсу за компоненту. Приликом одабира структуре за компоненте да би складиштиле децу, могуће је користити веома разноврсне структуре - од уланчаних листи, преко стабала, низова и хеш табела.

Испод је дат пример имплементације градитеља на програмском језику Јава, преузет са сајта који се може наћи на спољашњим линковима. Класе су, наравно, посебни фајлови и потребно је укључити одговарајуће пакете, али су овде приказани на једном месту.

//Klasa koja predstavlja Komponentu objektnog stabla public abstract class Component { private String name; public Component(String name) { this.name = name;

public abstract String operation(); public String getName() { return name;

//Default implementacija za operacije koje barataju decom public boolean add(Component child) { //Po default-u, vraca false return false;

public Iterator<Component> iterator() { // null iterator return Collections.<Component>emptyIterator();

//Klasa koja predstavlja List public class Leaf extends Component { public Leaf(String name) { super(name);

public String operation() { return getName();

//Klasa koja predstavlja Kompoziciju public class Composite extends Component { private List<Component> children = new ArrayList<Component>();

public Composite(String name) { super(name);

public String operation() { Iterator<Component> it = children.iterator(); String str = getName(); Component child; while (it.hasNext()) { child = it.next(); str += child.operation();

return str;

//Treba "pregaziti" (override) default operacije @Override public boolean add(Component child) { return children.add(child);

@Override public Iterator<Component> iterator() { return children.iterator();

Литература

Референце

Спољашње везе Composite (w3sDesign) - линк сајта са примером имплементације градитеља у Јави Composite (Javaworld)

Категорија:Пројектни узорци Категорија:Чланци са примерима Јава кода