?? pat3b.htm
字號:
<SCRIPT>
function setFocus() {
if ((navigator.appName != "Netscape") && (parseFloat(navigator.appVersion) == 2)) {
return;
} else {
self.focus();
}
}
</SCRIPT><HTML><HEAD> <TITLE>Builder</TITLE></HEAD><BODY BGCOLOR = #FFFFFF TEXT = #000000
onLoad="setFocus()";><A NAME="top"></A><A NAME="Builder"></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>Separate the construction of a complex object from its representationso that the same construction process can create differentrepresentations.</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>A reader for the RTF (Rich Text Format) document exchange formatshould be able to convert RTF to many text formats. The reader mightconvert RTF documents into plain ASCII text or into a text widget thatcan be edited interactively. The problem, however, is that the numberof possible conversions is open-ended. So it should be easy to add anew conversion without modifying the reader.</P><A NAME="rtfreader"></A><P>A solution is to configure the RTFReader class with a TextConverterobject that converts RTF to another textual representation. As theRTFReader parses the RTF document, it uses the TextConverter toperform the conversion. Whenever the RTFReader recognizes an RTFtoken (either plain text or an RTF control word), it issues a requestto the TextConverter to convert the token. TextConverter objects areresponsible both for performing the data conversion and forrepresenting the token in a particular format.</P><A NAME="tex"></A><P>Subclasses of TextConverter specialize in different conversions andformats. For example, an ASCIIConverter ignores requests to convertanything except plain text. A TeXConverter, on the other hand, willimplement operations for all requests in order to produce a TeXrepresentation that captures all the stylistic information in thetext. A TextWidgetConverter will produce a complex user interfaceobject that lets the user see and edit the text.</P><A NAME="rtfreader-97c"></A><P ALIGN=CENTER><IMG SRC="Pictures/build096.gif"></P><A NAME="auto1002"></A><P>Each kind of converter class takes the mechanism for creating andassembling a complex object and puts it behind an abstract interface.The converter is separate from the reader, which is responsible forparsing an RTF document.</P><A NAME="auto1003"></A><P>The Builder pattern captures all these relationships. Each converterclass is called a <STRONG>builder</STRONG> in the pattern, and the readeris called the <STRONG>director</STRONG>. Applied to this example, theBuilder pattern separates the algorithm for interpreting a textualformat (that is, the parser for RTF documents) from how a convertedformat gets created and represented. This lets us reuse theRTFReader's parsing algorithm to create different text representationsfrom RTF documents—just configure the RTFReader with differentsubclasses of TextConverter.</P><A NAME="applicability"></A><H2><A HREF="#structure"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Structure"></A> Applicability</H2><A NAME="auto1004"></A><P>Use the Builder pattern when</P><UL><A NAME="auto1005"></A><LI>the algorithm for creating a complex object should be independent of theparts that make up the object and how they're assembled.</P><A NAME="auto1006"></A><LI>the construction process must allow different representations for theobject that's constructed.</P></UL><A NAME="structure"></A><H2><A HREF="#participants"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Participants"></A> Structure</H2><A NAME="prod-98c"></A><P ALIGN=CENTER><IMG SRC="Pictures/builder.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="auto1007"></A><LI><B>Builder</B> (TextConverter)</LI><A NAME="auto1008"></A><P></P><UL> <A NAME="auto1009"></A><LI>specifies an abstract interface for creating parts of a Product object.</LI></UL><A NAME="auto1010"></A><P></P><A NAME="auto1011"></A><LI><B>ConcreteBuilder</B> (ASCIIConverter, TeXConverter, TextWidgetConverter)</LI><A NAME="auto1012"></A><P></P><UL> <A NAME="auto1013"></A><LI>constructs and assembles parts of the product by implementing the Builder interface.</LI> <A NAME="auto1014"></A><P><!-- extra space --></P> <A NAME="auto1015"></A><LI>defines and keeps track of the representation it creates.</LI> <A NAME="auto1016"></A><P><!-- extra space --></P> <A NAME="auto1017"></A><LI>provides an interface for retrieving the product (e.g., GetASCIIText, GetTextWidget).</LI></UL><A NAME="auto1018"></A><P></P><A NAME="director"></A><LI><B>Director</B> (RTFReader)</LI><A NAME="auto1019"></A><P></P><UL> <A NAME="auto1020"></A><LI>constructs an object using the Builder interface.</LI></UL><A NAME="auto1021"></A><P></P><A NAME="prod-part-build"></A><LI><B>Product</B> (ASCIIText, TeXText, TextWidget)</LI><A NAME="auto1022"></A><P></P><UL> <A NAME="auto1023"></A><LI>represents the complex object under construction. ConcreteBuilder builds the product's internal representation and defines the process by which it's assembled.</LI> <A NAME="auto1024"></A><P><!-- extra space --></P> <A NAME="auto1025"></A><LI>includes classes that define the constituent parts, including interfaces for assembling the parts into the final result.</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="auto1026"></A><LI>The client creates the Director object and configures it withthe desired Builder object.</LI><A NAME="auto1027"></A><P></P><A NAME="auto1028"></A><LI>Director notifies the builder whenever a part of the productshould be built.</LI><A NAME="auto1029"></A><P></P><A NAME="auto1030"></A><LI>Builder handles requests from the director and adds parts tothe product.</LI><A NAME="auto1031"></A><P></P><A NAME="auto1032"></A><LI>The client retrieves the product from the builder.</LI></UL><A NAME="auto1033"></A><P>The following interaction diagram illustrates how Builder and Directorcooperate with a client.</P><P ALIGN=CENTER><IMG SRC="Pictures/build095.gif"></P><A NAME="consequences"></A><H2><A HREF="#implementation"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Implementaion"></A> Consequences</H2><A NAME="auto1034"></A><P>Here are key consequences of the Builder pattern:</P><OL><A NAME="auto1035"></A><LI><EM>It lets you vary a product's internal representation.</EM>The Builder object provides the director with an abstract interfacefor constructing the product. The interface lets the builder hide therepresentation and internal structure of the product. It also hideshow the product gets assembled. Because the product is constructedthrough an abstract interface, all you have to do to change theproduct's internal representation is define a new kind of builder.</LI><A NAME="auto1036"></A><P></P><A NAME="auto1037"></A><LI><EM>It isolates code for construction and representation.</EM>The Builder pattern improves modularity by encapsulating the way acomplex object is constructed and represented. Clients needn't knowanything about the classes that define the product's internalstructure; such classes don't appear in Builder's interface.</LI><A NAME="auto1038"></A><P>Each ConcreteBuilder contains all the code to create and assemble aparticular kind of product. The code is written once; then differentDirectors can reuse it to build Product variants from the same set ofparts. In the earlier RTF example, we could define a reader for aformat other than RTF, say, an SGMLReader, and use the sameTextConverters to generate ASCIIText, TeXText, and TextWidgetrenditions of SGML documents.</LI><A NAME="auto1039"></A><P></P><A NAME="auto1040"></A><LI><EM>It gives you finer control over the construction process.</EM>Unlike creational patterns that construct products in one shot, theBuilder pattern constructs the product step by step under thedirector's control. Only when the product is finished does thedirector retrieve it from the builder. Hence the Builder interfacereflects the process of constructing the product more than othercreational patterns. This gives you finer control over theconstruction process and consequently the internal structure of theresulting product.</LI></OL><A NAME="implementation"></A><H2><A HREF="#samplecode"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Sample Code"></A> Implementation</H2><A NAME="auto1041"></A><P>Typically there's an abstract Builder class that defines an operationfor each component that a director may ask it to create. Theoperations do nothing by default. A ConcreteBuilder class overridesoperations for components it's interested in creating.</P><A NAME="auto1042"></A><P>Here are other implementation issues to consider:</P><OL><A NAME="auto1043"></A><LI><EM>Assembly and construction interface.</EM>Builders construct their products in step-by-step fashion. Thereforethe Builder class interface must be general enough to allowthe construction of products for all kinds of concrete builders.<A NAME="auto1044"></A><P>A key design issue concerns the model for the construction andassembly process. A model where the results of construction requestsare simply appended to the product is usually sufficient. In the RTFexample, the builder converts and appends the next token to the textit has converted so far.</P><A NAME="auto1045"></A><P>But sometimes you might need access to parts of the productconstructed earlier. In the Maze example we present in the SampleCode, the MazeBuilder interface lets you add a door betweenexisting rooms. Tree structures such as parse trees that are builtbottom-up are another example. In that case, the builder would returnchild nodes to the director, which then would pass them back to thebuilder to build the parent nodes.</LI><A NAME="auto1046"></A><P></P><A NAME="auto1047"></A><LI><EM>Why no abstract class for products?</EM>In the common case, the products produced by the concrete buildersdiffer so greatly in their representation that there is little to gainfrom giving different products a common parent class. In the RTFexample, the ASCIIText and the TextWidget objects are unlikely to havea common interface, nor do they need one. Because the client usuallyconfigures the director with the proper concrete builder, the clientis in a position to know which concrete subclass of Builder is in useand can handle its products accordingly.</LI><A NAME="auto1048"></A><P></P><A NAME="auto1049"></A><LI><EM>Empty methods as default in Builder.</EM>In C++, the build methods are intentionally not declared pure virtualmember functions. They're defined as empty methods instead, lettingclients override only the operations they're interested in.</LI></OL><A NAME="samplecode"><A><H2><A HREF="#knownuses"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Known Uses"></A> Sample Code</H2><A NAME="auto1050"></A><P>We'll define a variant of the <CODE>CreateMaze</CODE> member function(<A HREF="chap3fs.htm#CreateMaze-def" TARGET="_mainDisplayFrame">page 84</A>) that takes a builder of class<CODE>MazeBuilder</CODE> as an argument.</P><A NAME="auto1051"></A><P>The <CODE>MazeBuilder</CODE> class defines the following interface forbuilding mazes:</P>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -