|
This does not cite any references or sources. Please help improve this article by adding citations to reliable sources. (help, get involved!) Any material not supported by sources may be challenged and removed at any time. This article has been tagged since June 2006. In computer science, the composite pattern is a design pattern: "A general solution to a common problem in software design." Computer science, or computing science, is the study of the theoretical foundations of information and computation and their implementation and application in computer systems. ...
{{Hide = {{{ Hybrid reference style allows grouped references at top, but uses m:Cite. ...
Motivation: In object-oriented programming, a Composite is an object (e.g. a shape) designed as a composition of one-or-more similar objects (other kinds of shapes/geometries), all exhibiting similar functionality. This is known as a "has-a" relationship between objects. The key concept is that you can manipulate a single instance of the object just as you would a group of them. The operations you can perform on all the composite objects often have a least common denominator relationship. For example, when resizing a single shape to fill the screen, surely you would expect/desire that resizing a group of shapes would have the same effect. Object-oriented programming (OOP) is a programming paradigm that uses objects to design applications and computer programs. ...
In database design and program architecture, Has-a is a relationship where one object belongs to another object, and behaves according to the rules of ownership. ...
In mathematics, the lowest common denominator or least common denominator (abbreviated LCD) is the least common multiple of the denominators of a set of vulgar fractions. ...
When to use: You find that you are using multiple objects in the same way, and often have nearly identical code to handle each of them -- the only differences being that you are manipulating an instance of a 'circle' versus a 'square', for instance. Useful if differentiation doesn't need to exist, and it would be easier to think of them as homogeneous. (Of course, you could still provide functionality to manipulate only a single instance -- like selecting an item from a list instead of operating on the whole list.) Compose means a special thing: it refers to building objects using DelegationConcept. Delegation-composition hangs onto constituent parts-using references. By contrast, mixins inherit from each part. MixIns prevent returning a WholeObject in response to requests for information, and they prevent having more than one of any given part. In object-oriented programming languages, a mixin is an approach to implementing classes that differs from the most widely-used approach coming from the programming language Simula. ...
The composite pattern is an object oriented pendant to algebraic data types. An algebraic data type is a datatype whose each value is data from other datatypes wrapped in one of the constructors of the datatype. ...
Structure
Image File history File links Compositepattern. ...
- Component
-
- is the abstraction for all components, including composite ones
- Leaf
-
- represents leaf objects in the composition
- implements all Component methods
- Composite
-
- represents a composite Component (component having children)
- implements methods to manipulate children
- implements all Component methods, generally by delegating them to its children
Examples The following examples implement a graphic class, which can be either an ellipse or a composition of several graphics. Every graphic can be printed. It could be extended to implement several other shapes (rectangle etc.) and methods (translate etc.).
C# using System; using System.Collections; public class Graphic { //Prints the graphic. public virtual void Print(); } public class CompositeGraphic : Graphic { //Collection of child graphics. private Collection<Graphic> mChildGraphics; //Prints the graphic. public override void Print() { foreach(Graphic graphic in 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); } } public class Ellipse : Graphic { //Prints the graphic. public override void Print() { Console.WriteLn("Ellipse."); } } public static class Program { //Execute program. public static void Main() { //Initialize four ellipses Ellipse elipse1; Ellipse elipse2; Ellipse elipse3; Ellipse elipse4; //Initialize three composite graphics CompositeGraphic graphic; CompositeGraphic graphic1; CompositeGraphic graphic2; //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++ #include <iostream> #include <list> class Graphic { public: /// Print out the Graphic virtual void print() = 0; virtual ~Graphic() {}; }; class CompositeGraphic: public Graphic { public: CompositeGraphic() : Graphic(), _l() {} /// Add a children void addGraphic(Graphic* g) { _l.push_back(g); } /// Remove a children void removeGraphic(Graphic* g); void print() { // for each child ... for (std::list<Graphic*>::iterator it = _l.begin(); it != _l.end(); ++it) (*it)->print(); // ... print it } private: /// children std::list<Graphic*> _l; }; class Ellipse: public Graphic { public: /// Build an ellipse with the specified coordinates and radius Ellipse(int x, int y, unsigned radius) : Graphic(), _x(x), _y(y), _r(radius) {} virtual void print() { std::cout << "Ellipse(" << _x << ", " << _y << ", " << _r << ")" << std::endl; } private: int _x; int _y; unsigned _r; }; int main() { Ellipse* e1 = new Ellipse(42, 51, 69); Ellipse* e2 = new Ellipse(16, 64, 86); Ellipse* e3 = new Ellipse(1, 33, 7); CompositeGraphic* g1 = new CompositeGraphic(); CompositeGraphic g2; g1->addGraphic(e1); g1->addGraphic(e2); g2.addGraphic(g1); g2.addGraphic(e3); g2.print(); delete e1; delete e2; delete e3; delete g1; } JAVA The following JAVA program illustrates the previous.NET example again. // The "DefaultMethod()" was renamed to be "toString()" in this version. // requires JDK 1.5 or above, for generics List<E> and foreach loop // To compile and execute this code: // javac -cp . Main.java // java -cp . Main import java.util.List; import java.util.ArrayList; import java.util.Collection; public class Main { public static void main(String[] args) { Composite england = new Composite("England"); Leaf york = new Leaf("York"); Leaf london = new Leaf("London"); england.addComponent(york); england.addComponent(london); england.removeComponent(york); Composite france = new Composite("France"); france.addComponent(new Leaf("Paris")); Composite europe = new Composite("Europe"); europe.addComponent(england); europe.addComponent(france); System.out.println(europe.toString()); } } interface IComponent { // Warning: this is very wrong and breaks the OO conception. // Not all components have children. These methods shall be declared // and implemented in Composite only. Collection getChildren(); boolean addComponent(IComponent c); // add composite or leaf boolean removeComponent(IComponent c); } class Composite implements IComponent { private String id; private List<IComponent> list = new ArrayList<IComponent> (); public Composite(String id) { this.id = id; } public String toString() { StringBuilder buf = new StringBuilder(); buf.append(String.format("(%s:", id)); // JDK 1.5 "foreach" implicitly uses an iterator to walk over list for (IComponent child : list) { buf.append(" " + child.toString()); } buf.append(")"); return buf.toString(); } //public List<IComponent> getChildren() public Collection getChildren() { return list; } public boolean addComponent(IComponent c) { return list.add(c); } public boolean removeComponent(IComponent c) { return list.remove(c); } } class Leaf implements IComponent { private String id; public Leaf(String id) { this.id = id; } public String toString() { return this.id; } public Collection getChildren() { return null; } // false because failed to add public boolean addComponent(IComponent c) { return false; } // false because failed to find it for removal public boolean removeComponent(IComponent c) { return false; } } Perl The following Perl program illustrates the 'Europe' example given above and will output: (Europe: (England: London) (France: Paris)) package Composite; sub new { my($class, $identification) = @_; my $self = bless({ id => $identification, components => {}, }, $class); return $self; } sub default_method { my $self = shift; my $s = '(' . $self->{id} . ':'; foreach my $component (values %{ $self->{components} }) { $s .= ' ' . $component->default_method(); } return $s . ')'; } sub add_component { my($self, $component) = @_; $self->{components}{$component} = $component; } sub remove_component { my($self, $component) = @_; delete($self->{components}{$component}); } 1; package Leaf; sub new { my($class, $identification) = @_; my $self = bless({ id => $identification, }, $class); return $self; } sub default_method { my $self = shift; return $self->{id}; } 1; ### client my $england = Composite->new('England'); my $york = Leaf->new('York'); my $london = Leaf->new('London'); $england->add_component($york); $england->add_component($london); $england->remove_component($york); my $france = Composite->new('France'); $france->add_component(Leaf->new('Paris')); my $europe = Composite->new('Europe'); $europe->add_component($england); $europe->add_component($france); print $europe->default_method() . "n"; Perl (complex example) (needs revising) Objects may be members of a number of linked lists in our system. The linked lists organize the objects by different criteria. package LinkedList; use ImplicitThis; ImplicitThis::imply(); sub new { my $type = shift; bless { next=>'', previous=>'' }, $type; } sub next { return $next; } sub set_next { $next = shift; return 1; } sub previous { return $previous; } sub set_previous { $previous = shift; return 1; } sub append { my $ob = shift; $ob->isa(__PACKAGE__) or die; $next or do { $next = $ob; $ob->set_previous($this); return 1; } $ob->set_next($next); $next->set_previous($ob); $ob->set_previous($this); $this->set_next($ob); return 1; } This can be inherited, but inheriting it multiple times doesn't do any good: one only ever has one instance of the LinkedList this way - oneself. Using composition gives the desired result: In object-oriented programming of computer science, an inheritance is a way to form new classes (instances of which will be objects) using pre-defined objects or classes where new ones simply take over old ones implementations and characteristics. ...
package TriceQueuedObject; use LinkedList; use ImplicitThis; ImplicitThis::imply(); sub new { my $type = shift; my $me = { sort_order => new LinkedList, size_order => new LinkedList, save_order => new LinkedList, @_ }; bless $me, $type; } # create accessors that defer the action to each object, for each object composing us: # method A: see text below sub next_sort { return $sort_order->next(); } sub previous_sort { return $sort_order->previous(); } sub set_next_sort { return $sort_order->set_next(@_); } sub append_sort { return $sort_order->append(@_); } sub next_size { return $size_order->next(); } sub previous_size { return $size_order->previous(); } sub set_next_size { return $size_order->set_next(@_); } sub append_size { return $size_order->append(@_); } sub next_save { return $save_order->next(); } sub previous_save { return $save_order->previous(); } sub set_next_save { return $save_order->set_next(@_); } sub append_save { return $save_order->append(@_); } # directly return references to objects that compose us: # method B: see text below sub get_sort_order { return $sort_order; } sub get_size_order { return $size_order; } sub get_save_order { return $save_order; } "Method A" and "method B" illustrate two very different approaches to giving users of the object access to the parts. "Method A" creates all new accessors which do their work by calling accessors in the composing objects. "Method B" simply returns the composing objects and lets the user call the methods directly. For example: # using method A: $ob->next_sort($ob2); # using method B: $ob->get_sort_order()->set_next($ob2); Which method is preferable varies. If the object is merely a container for other objects, B makes more sense. If the object is a Facade, providing a new interface to several objects, A makes more sense. If the contained objects are considered to be implementation dependent, and having to support returning intermediate objects in the future is not desirable, A allows better hiding of the implementation. B makes for shorter code and less typing when the relationship between the objects is not likely to change. In object-oriented computer programming, a container class is a class of objects that is intended to contain other objects. ...
Each LinkedList instance is a "delegate" in this example. The methods that propagate requests to them are "delegate methods".
The following Visual Prolog program illustrates the 'Europe' example given above and will output: Visual Prolog, also formerly known as PDC Prolog and Turbo Prolog, is a strongly typed object-oriented extension of Prolog. ...
Visual Prolog, also formerly known as PDC Prolog and Turbo Prolog, is a strongly typed object-oriented extension of Prolog. ...
(Europe: (England: London) (France: Paris)) The component is object type, i.e. an interface: interface component predicates defaultMethod : () -> string StringRepresentation. getChildren : () -> component* Children. tryAddComponent : (component Child) determ. tryRemoveComponent : (component Child) determ. end interface component The composite is a class (this implementation uses a nondeterministic fact for the children, and list comprehension to get all children and to "format" the children). List comprehension is a programming language construct for list processing, analogous to the set-builder notation (set comprehension), that is, the mathematical notation such as the following: For an example, in Haskells list comprehension syntax, the example set-builder construct above would be written as: S = [ x | x<-[0. ...
class composite : component constructors new : (string Id). end class composite implement composite facts id : string. child_fact : (component Child) nondeterm. clauses new(Id) :- id := Id. clauses defaultMethod() = string::format("(%: %)", id, string::concatWithDelimiter( [ Child:defaultMethod() || child_fact(Child) ], " " )). clauses getChildren() = [ Child || child_fact(Child) ]. clauses tryAddComponent(Child) :- assert(child_fact(Child)). clauses tryRemoveComponent(Child) :- retract(child_fact(Child)), !. end implement composite The leaf is also a class. class leaf : component constructors new : (string Id). end class leaf implement leaf facts id : string. clauses new(Id) :- id := Id. clauses defaultMethod() = id. clauses getChildren() = []. clauses tryAddComponent(_Child) :- fail. clauses tryRemoveComponent(_Child) :- fail. end implement leaf Usage implement main clauses run() :- console::init(), England = composite::new("England"), York = leaf::new("York"), London = leaf::new("London"), England:tryAddComponent(York), England:tryAddComponent(London), England:tryRemoveComponent(York), France = composite::new("France"), France:tryAddComponent(leaf::new("Paris")), Europe = composite::new("Europe"), Europe:tryAddComponent(England), Europe:tryAddComponent(France), !, stdio::write( Europe:defaultMethod() ). run(). end implement main See also This article is about the book by Gamma et al. ...
In object-oriented programming languages, a mixin is an approach to implementing classes that differs from the most widely-used approach coming from the programming language Simula. ...
In computer programming, a facade is an object that provides a simplified interface to a larger body of code, such as a class library. ...
In object-oriented programming, a decorator pattern is a design pattern. ...
The Law of Demeter (LoD) is a design guideline for developing software, particularly object-oriented programs. ...
In software engineering, the delegation pattern is a technique where an object outwardly expresses certain behaviour but in reality delegates responsibility for implementing that behavior to an associated object in an Inversion of Responsibility. ...
Oftentimes, builder pattern builds Composite pattern, a structure pattern. ...
A software design pattern, the Abstract Factory Pattern provides a way to encapsulate a group of individual factories that have a common theme. ...
External links - Description from the Portland Pattern Repository
- Class::Delegation on CPAN
- Chinese Ring Puzzle Applet
- "The End of Inheritance: Automatic Run-time Interface Building for Aggregated Objects" by Paul Baranowski
- Composite Pattern by Vince Huston
- A persistent implementation of the Composite Pattern using Hibernate
- Note the above isn't a representation of the Composite Pattern
Parts of this article originated from the Perl Design Patterns Book Perl Design Patterns Book is an online textbook about Perl style and design and analysis. ...
Creational: Abstract factory • Builder • Factory • Prototype • Singleton {{Hide = {{{ Hybrid reference style allows grouped references at top, but uses m:Cite. ...
This article is about the book by Gamma et al. ...
A software design pattern, the Abstract Factory Pattern provides a way to encapsulate a group of individual factories that have a common theme. ...
Oftentimes, builder pattern builds Composite pattern, a structure pattern. ...
The factory method pattern is an object-oriented design pattern. ...
A prototype pattern is a creational design pattern used in software development when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects. ...
In software engineering, the singleton pattern is a design pattern that is used to restrict instantiation of a class to one object. ...
Structural: Adapter • Bridge • Composite • Decorator • Façade • Flyweight • Proxy In computer programming, the adapter design pattern (sometimes referred to as the wrapper pattern or simply a wrapper) adapts one interface for a class into one that a client expects. ...
The bridge pattern is a design pattern used in software engineering which is meant to decouple an abstraction from its implementation so that the two can vary independently (Gamma et. ...
In object-oriented programming, a decorator pattern is a design pattern. ...
The façade pattern is an object-oriented design pattern. ...
Flyweight is a software design pattern. ...
// In computer programming, the proxy pattern is a software design pattern. ...
Behavorial: Chain of responsibility • Command • Interpreter • Iterator • Mediator • Memento • Observer • State • Strategy • Template method • Visitor In Object Oriented Design, the chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. ...
In object-oriented programming, the Command pattern is a design pattern in which objects are used to represent actions. ...
In computer programming, the interpreter pattern is a particular design pattern. ...
In object-oriented programming, an iterator is an object allowing one to sequence through all of the elements or parts contained in some other object, typically a container or list. ...
The mediator pattern is a software design pattern that provides a unified interface to a set of interfaces in a subsystem. ...
The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo by rollback). ...
// The observer pattern (sometimes known as publish/subscribe) is a design pattern used in computer programming to observe the state of an object in a program. ...
A behavioral software design pattern, state pattern is used in computer programming to represent the state of an object. ...
In computer programming, the strategy pattern is a particular software design pattern, whereby algorithms can be selected on-the-fly at runtime. ...
Template method: UML class diagram. ...
In object-oriented programming and software engineering, the visitor design pattern is a way of separating an algorithm from an object structure. ...
|