Composite pattern
In computer programming, composite pattern is one of design patterns to decompose objects into their parts, and reassemble them in whichever
combination you need with "has-a[?]" relationships. That is to say, break things
into the largest parts that still let you reuse the parts, and build your objects of those.
The other definition is to compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
When: Any time there is partial overlap in the capabilities of objects.
Objects may be members of a number of linked lists in our system. The linked
lists organize the objects by different criteria.
We can inherit this, but inheriting it multiple times doesn't do us any good:
we only ever have one instance of the LinkedList this way - ourselves. Using
composition gives us what we want:
Where it says "method A" and "method B" illustrate two very different approaches
to giving users of our object access to the our 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:
Which is better? Well, it depends. If your object is merely a container for
other objects, B makes more sense. If your object is a Facade, providing a new
interface to several objects, A makes more sense. If you consider the objects
you contain to be implementation dependent, and you don't want to have to support
returning intermediate objects in the future, A lets you hide your implementation
better. B makes for shorter code and less typing when the relationship between the
objects isn't likely to change.
Each LinkedList instance is a "delegate" in this example. The methods that
propogate requests to them are "delegate methods".
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 responce to requests for information,
and they prevent you from having a more than one of any given part.
The article is originally from Perl Design Patterns Book
package LinkedList;
use ImplictThis; 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;
}
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; }
# using method A:
$ob->next_sort($ob2);
# using method B:
$ob->get_sort_order()->set_next($ob2);
External Links
See Also: