⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pat4c-1.htm

📁 四人帮《设计模式》一书英文版本
💻 HTM
📖 第 1 页 / 共 3 页
字号:
children, including linked lists, trees, arrays, and hash tables.  The
choice of data structure depends (as always) on efficiency.  In fact,
it isn't even necessary to use a general-purpose data structure at
all.  Sometimes composites have a variable for each child, although this
requires each subclass of Composite to implement its own management
interface.  See <A HREF="pat5cfs-1.htm" tppabs="http://ultra/development/DesignPatterns/lowres/pat5cfs.htm" TARGET="_mainDisplayFrame">Interpreter (243)</A> for an example.</LI>

</OL>

<A NAME="samplecode"></A>
<H2><A HREF="#knownuses"><IMG SRC="down3-1.gif" tppabs="http://ultra/development/DesignPatterns/lowres/gifsb/down3.gif" BORDER=0 ALT="next: 
Known Uses"></A> Sample Code</H2> 

<A NAME="auto1082"></A>
<P>Equipment such as computers and stereo components are often organized
into part-whole or containment hierarchies. For example, a chassis can
contain drives and planar boards, a bus can contain cards, and a
cabinet can contain chassis, buses, and so forth. Such structures can
be modeled naturally with the Composite pattern.</P>

<A NAME="auto1083"></A>
<P><CODE>Equipment</CODE> class defines an interface for all equipment in
the part-whole hierarchy.</P>

<A NAME="auto1084"></A>
<PRE>
    class Equipment {
    public:
        virtual ~Equipment();
    
        const char* Name() { return _name; }
    
        virtual Watt Power();
        virtual Currency NetPrice();
        virtual Currency DiscountPrice();
    
        virtual void Add(Equipment*);
        virtual void Remove(Equipment*);
        virtual Iterator<Equipment*>* CreateIterator();
    protected:
        Equipment(const char*);
    private:
        const char* _name;
    };
</PRE>

<A NAME="auto1085"></A>
<P><CODE>Equipment</CODE> declares operations that return the
attributes of a piece of equipment, like its power consumption and
cost. Subclasses implement these operations for specific kinds of
equipment. <CODE>Equipment</CODE> also declares a
<CODE>CreateIterator</CODE> operation that returns an <CODE>Iterator</CODE>
(see <A HREF="chapCfs-1.htm" tppabs="http://ultra/development/DesignPatterns/lowres/chapCfs.htm" TARGET="_mainDisplayFrame">Appendix&nbsp;C</A>)
for accessing its parts.  The
default implementation for this operation returns a NullIterator,
which iterates over the empty set.</P>

<A NAME="auto1086"></A>
<P>Subclasses of <CODE>Equipment</CODE> might include Leaf classes that
represent disk drives, integrated circuits, and switches:</P>

<A NAME="auto1087"></A>
<PRE>
    class FloppyDisk : public Equipment {
    public:
        FloppyDisk(const char*);
        virtual ~FloppyDisk();
    
        virtual Watt Power();
        virtual Currency NetPrice();
        virtual Currency DiscountPrice();
    };
</PRE>

<A NAME="auto1088"></A>
<P><CODE>CompositeEquipment</CODE> is the base class for equipment
that contains other equipment. It's also a subclass of
<CODE>Equipment</CODE>.</P>

<A NAME="auto1089"></A>
<PRE>
    class CompositeEquipment : public Equipment {
    public:
        virtual ~CompositeEquipment();
    
        virtual Watt Power();
        virtual Currency NetPrice();
        virtual Currency DiscountPrice();
    
        virtual void Add(Equipment*);
        virtual void Remove(Equipment*);
        virtual Iterator<Equipment*>* CreateIterator();
    
    protected:
        CompositeEquipment(const char*);
    private:
        List<Equipment*> _equipment;
    };
</PRE>

<A NAME="auto1090"></A>
<P><CODE>CompositeEquipment</CODE> defines the operations for accessing and
managing subequipment. The operations <CODE>Add</CODE> and
<CODE>Remove</CODE> insert and delete equipment from the list of equipment
stored in the <CODE>_equipment</CODE> member.  The operation
<CODE>CreateIterator</CODE> returns an iterator (specifically, an
instance of <CODE>ListIterator</CODE>) that will traverse this list.</P>

<A NAME="auto1091"></A>
<P>A default implementation of <CODE>NetPrice</CODE> might use
<CODE>CreateIterator</CODE> to sum the net prices of the
subequipment<SUP><A NAME="fn2"></A><A HREF="#footnote2">2</A></SUP>:</P>

<A NAME="auto1092"></A>
<PRE>
    Currency CompositeEquipment::NetPrice () {
        Iterator<Equipment*>* i = CreateIterator();
        Currency total = 0;
    
        for (i->First(); !i->IsDone(); i->Next()) {
            total += i->CurrentItem()->NetPrice();
        }
        delete i;
        return total;
    }
</PRE>

<A NAME="auto1093"></A>
<P>Now we can represent a computer chassis as a subclass of
<CODE>CompositeEquipment</CODE> called <CODE>Chassis</CODE>.
<CODE>Chassis</CODE> inherits the child-related operations from
<CODE>CompositeEquipment</CODE>.</P>

<A NAME="auto1094"></A>
<PRE>
    class Chassis : public CompositeEquipment {
    public:
        Chassis(const char*);
        virtual ~Chassis();
    
        virtual Watt Power();
        virtual Currency NetPrice();
        virtual Currency DiscountPrice();
    };
</PRE>

<A NAME="auto1095"></A>
<P>We can define other equipment containers such as
<CODE>Cabinet</CODE> and <CODE>Bus</CODE> in a similar way.
That gives us everything we need to assemble equipment into a (pretty
simple) personal computer:</P>

<A NAME="auto1096"></A>
<PRE>
    Cabinet* cabinet = new Cabinet("PC Cabinet");
    Chassis* chassis = new Chassis("PC Chassis");
    
    cabinet->Add(chassis);
    
    Bus* bus = new Bus("MCA Bus");
    bus->Add(new Card("16Mbs Token Ring"));
    
    chassis->Add(bus);
    chassis->Add(new FloppyDisk("3.5in Floppy"));
    
    cout &lt;&lt; "The net price is " &lt;&lt; chassis->NetPrice() &lt;&lt; endl;
</PRE>

<A NAME="knownuses"></A>
<H2><A HREF="#relatedpatterns"><IMG SRC="down3-1.gif" tppabs="http://ultra/development/DesignPatterns/lowres/gifsb/down3.gif" BORDER=0 
ALT="next: Related Patterns"></A> Known Uses</H2> 

<A NAME="auto1097"></A>
<P>Examples of the Composite pattern can be found in almost all
object-oriented systems.  The original View class of Smalltalk
Model/View/Controller [<A HREF="bibfs-1.htm#krasner_mvc" tppabs="http://ultra/development/DesignPatterns/lowres/bibfs.htm#krasner_mvc" TARGET="_mainDisplayFrame">KP88</A>] was a Composite, and nearly every user interface
toolkit or framework has followed in its steps, including ET++ (with
its VObjects [<A HREF="bibfs-1.htm#et++" tppabs="http://ultra/development/DesignPatterns/lowres/bibfs.htm#et++" TARGET="_mainDisplayFrame">WGM88</A>]) and InterViews (Styles [<A HREF="bibfs-1.htm#InterViews3.1" tppabs="http://ultra/development/DesignPatterns/lowres/bibfs.htm#InterViews3.1" TARGET="_mainDisplayFrame">LCI+92</A>],
Graphics [<A HREF="bibfs-1.htm#interviews_graphic" tppabs="http://ultra/development/DesignPatterns/lowres/bibfs.htm#interviews_graphic" TARGET="_mainDisplayFrame">VL88</A>], and
Glyphs [<A HREF="bibfs-1.htm#interviews_glyphs" tppabs="http://ultra/development/DesignPatterns/lowres/bibfs.htm#interviews_glyphs" TARGET="_mainDisplayFrame">CL90</A>]).  It's interesting to note that the
original View of Model/View/Controller had a set of subviews; in other words, View was
both the Component class and the Composite class.  Release 4.0 of
Smalltalk-80 revised Model/View/Controller with a VisualComponent class that has
subclasses View and CompositeView.</P>

<A NAME="rtlsmall-use-comp"></A>
<A NAME="ssa"></A>
<P>The RTL Smalltalk compiler framework [<A HREF="bibfs-1.htm#RTLSystem92" tppabs="http://ultra/development/DesignPatterns/lowres/bibfs.htm#RTLSystem92" TARGET="_mainDisplayFrame">JML92</A>] uses the
Composite pattern extensively.  RTLExpression is a Component class for
parse trees. It has subclasses, such as BinaryExpression, that contain
child RTLExpression objects.  These classes define a composite
structure for parse trees.  RegisterTransfer is the Component class
for a program's intermediate Single Static Assignment (SSA) form.
Leaf subclasses of RegisterTransfer define different static
assignments such as</P>

<UL>

<A NAME="auto1098"></A>
<LI>primitive assignments that perform an operation on two registers and
assign the result to a third;</LI>
<A NAME="auto1099"></A>
<P></P>
<A NAME="auto1100"></A>
<LI>an assignment with a source register but no destination register,
which indicates that the register is used after a routine returns; and</LI>
<A NAME="auto1101"></A>
<P></P>
<A NAME="auto1102"></A>
<LI>an assignment with a destination register but no source, which
indicates that the register is assigned before the routine starts.</LI>

</UL>

<A NAME="auto1103"></A>
<P>Another subclass, RegisterTransferSet, is a Composite class
for representing assignments that change several registers at once.</P>

<A NAME="auto1104"></A>
<P>Another example of this pattern occurs in the financial domain, where
a portfolio aggregates individual assets.  You can support complex
aggregations of assets by implementing a portfolio as a Composite that
conforms to the interface of an individual
asset [<A HREF="bibfs-1.htm#birrer-egg_swaps" tppabs="http://ultra/development/DesignPatterns/lowres/bibfs.htm#birrer-egg_swaps" TARGET="_mainDisplayFrame">BE93</A>].</P>

<A NAME="auto1105"></A>
<P>The <A HREF="pat5bfs-1.htm" tppabs="http://ultra/development/DesignPatterns/lowres/pat5bfs.htm" TARGET="_mainDisplayFrame">Command (233)</A> pattern describes how Command objects
can be composed and sequenced with a MacroCommand Composite class.</P>

<A NAME="relatedpatterns"></A>
<H2><A HREF="#last"><IMG SRC="down3-1.gif" tppabs="http://ultra/development/DesignPatterns/lowres/gifsb/down3.gif" BORDER=0 ALT="next: 
navigation"></A> Related Patterns</H2> 

<A NAME="auto1106"></A>
<P>Often the component-parent link is used for a <A HREF="pat5afs-1.htm" tppabs="http://ultra/development/DesignPatterns/lowres/pat5afs.htm"
TARGET="_mainDisplayFrame">Chain of Responsibility (223)</A>.</P>

<A NAME="compcomposite"></A>
<P><A HREF="pat4dfs-1.htm" tppabs="http://ultra/development/DesignPatterns/lowres/pat4dfs.htm" TARGET="_mainDisplayFrame">Decorator (175)</A> is
often used with Composite.  When decorators and composites are used
together, they will usually have a common parent class.  So decorators
will have to support the Component interface with operations like
Add, Remove, and GetChild.</P>

<A NAME="auto1107"></A>
<P><A HREF="pat4ffs-1.htm" tppabs="http://ultra/development/DesignPatterns/lowres/pat4ffs.htm" TARGET="_mainDisplayFrame">Flyweight (195)</A>
lets you share components, but they can no longer refer to their
parents.</P>

<A NAME="auto1108"></A>
<P><A HREF="pat5dfs-1.htm" tppabs="http://ultra/development/DesignPatterns/lowres/pat5dfs.htm" TARGET="_mainDisplayFrame">Iterator (257)</A> can
be used to traverse composites.</P>

<A NAME="auto1109"></A>
<P><A HREF="pat5kfs-1.htm" tppabs="http://ultra/development/DesignPatterns/lowres/pat5kfs.htm" TARGET="_mainDisplayFrame">Visitor (331)</A>
localizes operations and behavior that would otherwise be distributed
across Composite and Leaf classes.</P>

<A NAME="last"></A>
<P><A HREF="#intent"><IMG SRC="up3-1.gif" tppabs="http://ultra/development/DesignPatterns/lowres/gifsb/up3.gif" BORDER=0></A><BR>
<A HREF="pat4dfs-1.htm" tppabs="http://ultra/development/DesignPatterns/lowres/pat4dfs.htm" TARGET="_mainDisplayFrame"><IMG SRC="rightar3-1.gif" tppabs="http://ultra/development/DesignPatterns/lowres/gifsb/rightar3.gif"
	ALIGN=TOP BORDER=0></A> <A HREF="pat4dfs-1.htm" tppabs="http://ultra/development/DesignPatterns/lowres/pat4dfs.htm"
	TARGET="_mainDisplayFrame">Decorator</A><BR>
<A HREF="pat4bfs-1.htm" tppabs="http://ultra/development/DesignPatterns/lowres/pat4bfs.htm" TARGET="_mainDisplayFrame"><IMG SRC="leftarr3-1.gif" tppabs="http://ultra/development/DesignPatterns/lowres/gifsb/leftarr3.gif"
	ALIGN=TOP BORDER=0></A> <A HREF="pat4bfs-1.htm" tppabs="http://ultra/development/DesignPatterns/lowres/pat4bfs.htm"
	TARGET="_mainDisplayFrame">Bridge</A>
</P>

<HR>

<A NAME="footnote2"></A>
<P><SUP>2</SUP>It's easy to forget to delete
the iterator once you're done with it.  The Iterator pattern shows
how to guard against such bugs on
<A HREF="pat5dfs-1.htm#clean-up_proxy_for_iterators" tppabs="http://ultra/development/DesignPatterns/lowres/pat5dfs.htm#clean-up_proxy_for_iterators" TARGET="_mainDisplayFrame">page 266</A>.</P>

</BODY>

</HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -