?? pat4f.htm
字號:
<SCRIPT>
function setFocus() {
if ((navigator.appName != "Netscape") && (parseFloat(navigator.appVersion) == 2)) {
return;
} else {
self.focus();
}
}
</SCRIPT><HTML><HEAD> <TITLE>Flyweight</TITLE></HEAD><BODY BGCOLOR = #FFFFFF TEXT = #000000
onLoad="setFocus()";><A NAME="top"></A><A NAME="Flyweight"></A><A NAME="intent"></A><H2><A HREF="#motivation"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Motivation"></A> Intent</H2> <A NAME="auto1000"></A><P>Use sharing to support large numbers of fine-grained objects efficiently.</P><A NAME="motivation"></A><H2><A HREF="#applicability"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Applicability"></A> Motivation</H2> <A NAME="auto1001"></A><P>Some applications could benefit from using objects throughout theirdesign, but a naive implementation would be prohibitively expensive.</P><A NAME="auto1002"></A><P>For example, most document editor implementations have text formattingand editing facilities that are modularized to some extent.Object-oriented document editors typically use objects to representembedded elements like tables and figures. However, they usually stopshort of using an object for each character in the document, eventhough doing so would promote flexibility at the finest levels in theapplication. Characters and embedded elements could then be treateduniformly with respect to how they are drawn and formatted. Theapplication could be extended to support new character sets withoutdisturbing other functionality. The application's object structurecould mimic the document's physical structure. The following diagram shows how a document editor can use objects to represent characters.</P><P ALIGN=CENTER><IMG SRC="Pictures/flywe055.gif"></P><A NAME="auto1003"></A><P>The drawback of such a design is its cost. Even moderate-sizeddocuments may require hundreds of thousands of character objects,which will consume lots of memory and may incur unacceptable run-timeoverhead. The Flyweight pattern describes how to share objects toallow their use at fine granularities without prohibitive cost.</P><A NAME="def-flywt"></A><A NAME="def-extrinsicstate"></A><A NAME="def-intrinsicstate"></A><P>A <STRONG>flyweight</STRONG> is a shared object that can be used inmultiple contexts simultaneously. The flyweight acts as an independentobject in each context—it's indistinguishable from an instance ofthe object that's not shared. Flyweights cannot make assumptions aboutthe context in which they operate. The key concept here is thedistinction between <STRONG>intrinsic</STRONG> and <STRONG>extrinsic</STRONG>state. Intrinsic state is stored in the flyweight; it consists ofinformation that's independent of the flyweight's context, therebymaking it sharable. Extrinsic state depends on and varies with theflyweight's context and therefore can't be shared. Client objects areresponsible for passing extrinsic state to the flyweight when it needsit.</P><A NAME="auto1004"></A><P>Flyweights model concepts or entities that are normally too plentifulto represent with objects. For example, a document editor can create aflyweight for each letter of the alphabet. Each flyweight stores acharacter code, but its coordinate position in the document and itstypographic style can be determined from the text layout algorithmsand formatting commands in effect wherever the character appears. Thecharacter code is intrinsic state, while the other information isextrinsic.</P><A NAME="auto1005"></A><P>Logically there is an object for every occurrence of a given character inthe document:</P><A NAME="flywt-eg-logic"></A><P ALIGN=CENTER><IMG SRC="Pictures/flywe054.gif"></P><A NAME="auto1006"></A><P>Physically, however, there is one shared flyweight object percharacter, and it appears in different contexts in the documentstructure. Each occurrence of a particular character object refers tothe same instance in the shared pool of flyweight objects:</P><P ALIGN=CENTER><IMG SRC="Pictures/flywe052.gif"></P><A NAME="auto1007"></A><P>The class structure for these objects is shown next. Glyph is theabstract class for graphical objects, some of which may be flyweights.Operations that may depend on extrinsic state have it passed to themas a parameter. For example, Draw and Intersects must know whichcontext the glyph is in before they can do their job.</P><P ALIGN=CENTER><IMG SRC="Pictures/flywe053.gif"></P><A NAME="auto1008"></A><P>A flyweight representing the letter "a" only stores thecorresponding character code; it doesn't need to store its location orfont. Clients supply the context-dependent information that theflyweight needs to draw itself. For example, a Row glyph knows whereits children should draw themselves so that they are tiledhorizontally. Thus it can pass each child its location in the drawrequest.</P><A NAME="auto1009"></A><P>Because the number of different character objects is far less than thenumber of characters in the document, the total number of objects issubstantially less than what a naive implementation would use. Adocument in which all characters appear in the same font and colorwill allocate on the order of 100 character objects (roughly the sizeof the ASCII character set) regardless of the document's length. Andsince most documents use no more than 10 different font-colorcombinations, this number won't grow appreciably in practice. Anobject abstraction thus becomes practical for individual characters.</P><A NAME="applicability"></A><H2><A HREF="#structure"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Structure"></A> Applicability</H2> <A NAME="auto1010"></A><P>The Flyweight pattern's effectiveness depends heavily on how and whereit's used. Apply the Flyweight pattern when <EM>all</EM> of the followingare true:</P><UL><A NAME="auto1011"></A><LI>An application uses a large number of objects.</LI><A NAME="auto1012"></A><P></P><A NAME="auto1013"></A><LI>Storage costs are high because of the sheer quantity of objects.</LI><A NAME="auto1014"></A><P></P><A NAME="auto1015"></A><LI>Most object state can be made extrinsic.</LI><A NAME="auto1016"></A><P></P><A NAME="auto1017"></A><LI>Many groups of objects may be replaced by relatively few sharedobjects once extrinsic state is removed.</LI><A NAME="auto1018"></A><P></P><A NAME="auto1019"></A><LI>The application doesn't depend on object identity. Since flyweightobjects may be shared, identity tests will return true for conceptuallydistinct objects.</LI></UL><A NAME="structure"></A><H2><A HREF="#participants"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Participants"></A> Structure</H2> <P ALIGN=CENTER><IMG SRC="Pictures/flywe050.gif"></P><A NAME="auto1020"></A><P>The following object diagram shows how flyweights are shared:</P><P ALIGN=CENTER><IMG SRC="Pictures/flywe051.gif"></P><A NAME="participants"></A><H2><A HREF="#collaborations"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Collaborations"></A> Participants</H2><UL><A NAME="auto1021"></A><LI><B>Flyweight</B><A NAME="auto1022"></A><P></P><UL> <A NAME="auto1023"></A><LI>declares an interface through which flyweights can receive and act on extrinsic state.</LI></UL><A NAME="auto1024"></A><P></P><A NAME="auto1025"></A><LI><B>ConcreteFlyweight</B> (Character)</LI><A NAME="auto1026"></A><P></P><UL> <A NAME="auto1027"></A><LI>implements the Flyweight interface and adds storage for intrinsic state, if any. A ConcreteFlyweight object must be sharable. Any state it stores must be intrinsic; that is, it must be independent of the ConcreteFlyweight object's context.</LI></UL><A NAME="auto1028"></A><P></P><A NAME="unsharconcflywt"></A><LI><B>UnsharedConcreteFlyweight</B> (Row, Column)</LI><A NAME="auto1029"></A><P></P><UL> <A NAME="auto1030"></A><LI>not all Flyweight subclasses need to be shared. The Flyweight interface <EM>enables</EM> sharing; it doesn't enforce it. It's common for UnsharedConcreteFlyweight objects to have ConcreteFlyweight objects as children at some level in the flyweight object structure (as the Row and Column classes have).</LI></UL><A NAME="auto1031"></A><P></P><A NAME="flywtfact-part"></A><LI><B>FlyweightFactory</B></LI><A NAME="auto1032"></A><P></P><UL> <A NAME="auto1033"></A><LI>creates and manages flyweight objects.</LI> <A NAME="auto1034"></A><P><!-- extra space --></P> <A NAME="auto1035"></A><LI>ensures that flyweights are shared properly. When a client requests a flyweight, the FlyweightFactory object supplies an existing instance or creates one, if none exists.</UL><A NAME="auto1036"></A><P></P><A NAME="auto1037"></A><LI><B>Client</B></LI><A NAME="auto1038"></A><P></P><UL> <A NAME="auto1039"></A><LI>maintains a reference to flyweight(s).</LI> <A NAME="auto1040"></A><P><!-- extra space --></P> <A NAME="auto1041"></A><LI>computes or stores the extrinsic state of flyweight(s).</LI></UL></UL><A NAME="collaborations"></A><H2><A HREF="#consequences"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Consequences"></A> Collaborations</H2><UL><A NAME="auto1042"></A><LI>State that a flyweight needs to function must be characterized aseither intrinsic or extrinsic. Intrinsic state is stored in theConcreteFlyweight object; extrinsic state is stored or computed byClient objects. Clients pass this state to the flyweight whenthey invoke its operations.</LI><A NAME="auto1043"></A><P></P><A NAME="auto1044"></A><LI>Clients should not instantiate ConcreteFlyweights directly. Clientsmust obtain ConcreteFlyweight objects exclusively from theFlyweightFactory object to ensure they are shared properly.</LI></UL><A NAME="consequences"></A><H2><A HREF="#implementation"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Implementation"></A> Consequences</H2> <A NAME="auto1045"></A><P>Flyweights may introduce run-time costs associated with transferring,finding, and/or computing extrinsic state, especially if it wasformerly stored as intrinsic state. However, such costs are offset byspace savings, which increase as more flyweights are shared.</P><A NAME="auto1046"></A><P>Storage savings are a function of several factors:</P><UL><A NAME="auto1047"></A><LI>the reduction in the total number of instances that comes fromsharing</LI><A NAME="auto1048"></A><P></P><A NAME="auto1049"></A><LI>the amount of intrinsic state per object</LI><A NAME="auto1050"></A><P></P><A NAME="auto1051"></A><LI>whether extrinsic state is computed or stored.</LI></UL><A NAME="auto1052"></A><P>The more flyweights are shared, the greater the storage savings. Thesavings increase with the amount of shared state. The greatestsavings occur when the objects use substantial quantities of bothintrinsic and extrinsic state, and the extrinsic state can be computedrather than stored. Then you save on storage in two ways: Sharingreduces the cost of intrinsic state, and you trade extrinsic state forcomputation time.</P><A NAME="flywt-w-compst"></A><P>The Flyweight pattern is often combined with the<A HREF="pat4cfs.htm" TARGET="_mainDisplayFrame">Composite (163)</A> pattern to represent a hierarchicalstructure as a graph with shared leaf nodes. A consequence of sharingis that flyweight leaf nodes cannot store a pointer to their parent.Rather, the parent pointer is passed to the flyweight as part of itsextrinsic state. This has a major impact on how the objects in thehierarchy communicate with each other.</P><A NAME="implementation"></A><H2><A HREF="#samplecode"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Sample Code"></A> Implementation</H2> <A NAME="auto1053"></A><P>Consider the following issues when implementing the Flyweight pattern:</P><OL><A NAME="auto1054"></A><LI><EM>Removing extrinsic state.</EM>The pattern's applicability is determined largely by how easy it is toidentify extrinsic state and remove it from shared objects. Removingextrinsic state won't help reduce storage costs if there are as manydifferent kinds of extrinsic state as there are objects beforesharing. Ideally, extrinsic state can be computed from a separateobject structure, one with far smaller storage requirements.<A NAME="auto1055"></A><P>In our document editor, for example, we can store a map of typographicinformation in a separate structure rather than store the font andtype style with each character object. The map keeps track of runs ofcharacters with the same typographic attributes. When a characterdraws itself, it receives its typographic attributes as a side-effectof the draw traversal. Because documents normally use just a fewdifferent fonts and styles, storing this information externally toeach character object is far more efficient than storing itinternally.</P>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -