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

📄 pat4e.htm

📁 Design Pattern 设计模式
💻 HTM
📖 第 1 页 / 共 2 页
字号:
        istream&amp; _inputStream;    };</PRE><A NAME="auto1044"></A><P>The class <CODE>Parser</CODE> uses a <CODE>ProgramNodeBuilder</CODE> to construct aparse tree from a <CODE>Scanner</CODE>'s tokens.</P><A NAME="auto1045"></A><PRE>    class Parser {    public:        Parser();        virtual ~Parser();            virtual void Parse(Scanner&amp;, ProgramNodeBuilder&amp;);    };</PRE><A NAME="auto1046"></A><P><CODE>Parser</CODE> calls back on <CODE>ProgramNodeBuilder</CODE> to buildthe parse tree incrementally.  These classes interact according to the<A HREF="pat3bfs.htm" TARGET="_mainDisplayFrame">Builder (97)</A> pattern.</P><A NAME="auto1047"></A><PRE>    class ProgramNodeBuilder {    public:        ProgramNodeBuilder();            virtual ProgramNode* NewVariable(            const char* variableName        ) const;            virtual ProgramNode* NewAssignment(            ProgramNode* variable, ProgramNode* expression        ) const;            virtual ProgramNode* NewReturnStatement(            ProgramNode* value        ) const;            virtual ProgramNode* NewCondition(            ProgramNode* condition,            ProgramNode* truePart, ProgramNode* falsePart        ) const;        // ...            ProgramNode* GetRootNode();    private:        ProgramNode* _node;    };</PRE><A NAME="auto1048"></A><P>The parse tree is made up of instances of <CODE>ProgramNode</CODE>subclasses such as <CODE>StatementNode</CODE>,<CODE>ExpressionNode</CODE>, and so forth.  The <CODE>ProgramNode</CODE>hierarchy is an example of the <A HREF="pat4cfs.htm" TARGET="_mainDisplayFrame">Composite (163)</A>pattern. <CODE>ProgramNode</CODE> defines an interface for manipulatingthe program node and its children, if any.</P><A NAME="auto1049"></A><PRE>    class ProgramNode {    public:        // program node manipulation        virtual void GetSourcePosition(int&amp; line, int&amp; index);        // ...            // child manipulation        virtual void Add(ProgramNode*);        virtual void Remove(ProgramNode*);        // ...            virtual void Traverse(CodeGenerator&amp;);    protected:        ProgramNode();    };</PRE><A NAME="visit-in-compiler"></A><P>The <CODE>Traverse</CODE> operation takes a <CODE>CodeGenerator</CODE>object.  <CODE>ProgramNode</CODE> subclasses use this object to generatemachine code in the form of <CODE>Bytecode</CODE> objects on a<CODE>BytecodeStream</CODE>.  The class <CODE>CodeGenerator</CODE> is avisitor (see <A HREF="pat5kfs.htm" TARGET="_mainDisplayFrame">Visitor (331)</A>).</P><A NAME="auto1050"></A><PRE>    class CodeGenerator {    public:        virtual void Visit(StatementNode*);        virtual void Visit(ExpressionNode*);        // ...    protected:        CodeGenerator(BytecodeStream&amp;);    protected:        BytecodeStream&amp; _output;    };</PRE><A NAME="auto1051"></A><P><CODE>CodeGenerator</CODE> has subclasses, for example,<CODE>StackMachineCodeGenerator</CODE> and <CODE>RISCCodeGenerator</CODE>,that generate machine code for different hardware architectures.</P><A NAME="auto1052"></A><P>Each subclass of <CODE>ProgramNode</CODE> implements <CODE>Traverse</CODE>to call <CODE>Traverse</CODE> on its child <CODE>ProgramNode</CODE>objects.  In turn, each child does the same for its children, and soon recursively.  For example, <CODE>ExpressionNode</CODE> defines<CODE>Traverse</CODE> as follows:</P><A NAME="auto1053"></A><PRE>    void ExpressionNode::Traverse (CodeGenerator&amp; cg) {        cg.Visit(this);            ListIterator<ProgramNode*> i(_children);            for (i.First(); !i.IsDone(); i.Next()) {            i.CurrentItem()->Traverse(cg);        }    }</PRE><A NAME="auto1054"></A><P>The classes we've discussed so far make up the compiler subsystem.Now we'll introduce a <CODE>Compiler</CODE> class, a facade that puts allthese pieces together.  <CODE>Compiler</CODE> provides a simple interfacefor compiling source and generating code for a particular machine.</P><A NAME="auto1055"></A><PRE>    class Compiler {    public:        Compiler();            virtual void Compile(istream&amp;, BytecodeStream&amp;);    };        void Compiler::Compile (        istream&amp; input, BytecodeStream&amp; output    ) {        Scanner scanner(input);        ProgramNodeBuilder builder;        Parser parser;            parser.Parse(scanner, builder);            RISCCodeGenerator generator(output);        ProgramNode* parseTree = builder.GetRootNode();        parseTree->Traverse(generator);    }</PRE><A NAME="auto1056"></A><P>This implementation hard-codes the type of code generator to use sothat programmers aren't required to specify the target architecture.That might be reasonable if there's only ever one target architecture.If that's not the case, then we might want to change the<CODE>Compiler</CODE> constructor to take a <CODE>CodeGenerator</CODE>parameter.  Then programmers can specify the generator to use whenthey instantiate <CODE>Compiler</CODE>.  The compiler facade canparameterize other participants such as <CODE>Scanner</CODE> and<CODE>ProgramNodeBuilder</CODE> as well, which adds flexibility, but it alsodetracts from the Facade pattern's mission, which is to simplify theinterface for the common case.</P><A NAME="knownuses"><A><H2><A HREF="#relatedpatterns"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Related Patterns"></A> Known Uses</H2> <A NAME="auto1057"></A><P>The compiler example in the Sample Code section was inspired by theObjectWorks\Smalltalk compiler system [<A HREF="bibfs.htm#parcplace_smalltalk" TARGET="_mainDisplayFrame">Par90</A>].</P><A NAME="et-use-facade"></A><P>In the ET++ application framework [<A HREF="bibfs.htm#et++" TARGET="_mainDisplayFrame">WGM88</A>], an application can havebuilt-in browsing tools for inspecting its objects at run-time.  Thesebrowsing tools are implemented in a separate subsystem that includes aFacade class called "ProgrammingEnvironment."  This facade definesoperations such as InspectObject and InspectClass for accessing thebrowsers.</P><A NAME="auto1058"></A><P>An ET++ application can also forgo built-in browsing support.  Inthat case, ProgrammingEnvironment implements these requests as nulloperations; that is, they do nothing.  Only theETProgrammingEnvironment subclass implements these requests withoperations that display the corresponding browsers.  The applicationhas no knowledge of whether a browsing environment is available ornot; there's abstract coupling between the application and thebrowsing subsystem.</P><A NAME="domain"></A><A NAME="facade-use"></A><P>The Choices operating system [<A HREF="bibfs.htm#choices_cacm" TARGET="_mainDisplayFrame">CIRM93</A>] uses facades tocompose many frameworks into one.  The key abstractions in Choices areprocesses, storage, and address spaces.  For each of theseabstractions there is a corresponding subsystem, implemented as aframework, that supports porting Choices to a variety of differenthardware platforms.  Two of these subsystems have a "representative"(i.e., facade). These representatives are FileSystemInterface (storage)and Domain (address spaces).</P><A NAME="facade-choices"></A><P ALIGN=CENTER><IMG SRC="Pictures/facad059.gif"></P><A NAME="virtual-memory"></A><P>For example, the virtual memory framework has Domain as its facade.  ADomain represents an address space.  It provides a mapping betweenvirtual addresses and offsets into memory objects, files, or backingstore.  The main operations on Domain support adding a memory objectat a particular address, removing a memory object, and handling a pagefault.</P><A NAME="auto1059"></A><P>As the preceding diagram shows, the virtual memory subsystem uses thefollowing components internally:</P><UL><A NAME="auto1060"></A><LI>MemoryObject represents a data store.</LI><A NAME="auto1061"></A><P></P><A NAME="strat-in-choices"></A><LI>MemoryObjectCache caches the data of MemoryObjects in physical memory.MemoryObjectCache is actually a <A HREF="pat5ifs.htm" TARGET="_mainDisplayFrame">Strategy (315)</A> thatlocalizes the caching policy.</LI><A NAME="auto1062"></A><P></P><A NAME="auto1063"></A><LI>AddressTranslation encapsulates the address translation hardware.</LI></UL><A NAME="auto1064"></A><P>The RepairFault operation is called whenever a page fault interruptoccurs.  The Domain finds the memory object at the address causing thefault and delegates the RepairFault operation to the cache associatedwith that memory object.  Domains can be customized by changing theircomponents.</P><A NAME="relatedpatterns"></A><H2><A HREF="#last"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: navigation"></A> Related Patterns</H2> <A NAME="absfact"></A><P><A HREF="pat3afs.htm" TARGET="_mainDisplayFrame">Abstract Factory (87)</A>can be used with Facade to provide an interface for creatingsubsystem objects in a subsystem-independent way.  Abstract Factorycan also be used as an alternative to Facade to hide platform-specificclasses.</P><A NAME="facade-vs-med"></A><P><A HREF="pat5efs.htm" TARGET="_mainDisplayFrame">Mediator (273)</A> issimilar to Facade in that it abstracts functionality of existingclasses.  However, Mediator's purpose is to abstract arbitrarycommunication between colleague objects, often centralizingfunctionality that doesn't belong in any one of them.  A mediator'scolleagues are aware of and communicate with the mediator insteadof communicating with each other directly.  In contrast, a facademerely abstracts the interface to subsystem objects to make themeasier to use; it doesn't define new functionality, and subsystemclasses don't know about it.</P><A NAME="auto1065"></A><P>Usually only one Facade object is required.  Thus Facade objects areoften <A HREF="pat3efs.htm" TARGET="_mainDisplayFrame">Singletons (127)</A>.</P><A NAME="last"></A><P><A HREF="#intent"><IMG SRC="gifsb/up3.gif" BORDER=0></A><BR><A HREF="pat4ffs.htm" TARGET="_mainDisplayFrame"><IMG SRC="gifsb/rightar3.gif"	ALIGN=TOP BORDER=0></A> <A HREF="pat4ffs.htm"	TARGET="_mainDisplayFrame">Flyweight</A><BR><A HREF="pat4dfs.htm" TARGET="_mainDisplayFrame"><IMG SRC="gifsb/leftarr3.gif"	ALIGN=TOP BORDER=0></A> <A HREF="pat4dfs.htm"	TARGET="_mainDisplayFrame">Decorator</A></P></BODY></HTML>

⌨️ 快捷键说明

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