结构型模式--外观
作者:互联网
1、意图
为子系统中的一组接口提供一个一致的界面,外观模式(Facade)定义了一个高层接口,这个接口使得这一子系统更加容易使用。
2、结构
3、参与者
Facade:知道哪些子系统负责处理请求;将客户的请求代理给适当的子系统对象。
Subsystem classes:实现子系统的功能;处理由Facade对象指派的任务;没有facade的任何相关信息,即没有指向facade的指针;
4、适用性
在遇到以下情况使用外观模式:
当要为一个复杂子系统提供一个简单接口时。子系统往往因为不断演化而变得越来越复杂。大多数模式使用时都会产生更多更小的类。这使得子系统更具有可重用性,也更容易对子系统进行定制,但这也给那些不需要定制子系统的用户带来一些使用上的困难。Facade可以提供一个简单的缺省视图,这一视图对大多数用户来说已经足够,而那些需要更多的可定制性的用户可以越过facade层。
客户程序与抽象类的实现部分之间存在着很大的依赖性。引人facade将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。
5、代码示例
/ Scanner类接收字符流并产生一个标识符流,一次产生一个标识符(token)。 class Scanner { public: Scanner(istream&); virtual ~Scanner(); virtual Token& Scan(); private: istream& _inputstream; }; // Parser类,用Scanner生成的标识符和ProgramNodeBuilder构建一棵语法分析树。 class Parser { public: Parser(); virtual ~Parser(); virtual void Parse(Scanner&, ProgramNodeBuilder&); }; // Parser回调ProgramNodeBuilder逐步建立语法分析树,这些类遵循生成器模式(Builder)进行交互操作。 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; };
// 语法分析树由ProgramNode子类(例如StatementNode和ExpressionNode等)的实例构成。 // ProgramNode层次结构是组合模式(Composite)的一个应用实例。ProgramNode定义了一个 // 接口用于操作程序节点和它的子节点(如果有的话)。 class ProgramNode { public: // program node manipulation virtual void GetSourcePosition(int& line, int& index); // child manipulation virtual void Add(ProgramNode*); virtual void Remove(ProgramNode*); // ... virtual void Traverse(CodeGenerator&); protected: ProgramNode(); }; // Traverse操作以一个CodeGenerator对象为参数,ProgramNode子类使用这个对象产生机器代码, // 机器代码格式为BytecodeStream中的ByteCode对象。其中的CodeGenerator类是一个访问者(观察者模式(Visitor))。 class CodeGenerator { public: virtual void visit(StatementNode*); virtual void visit(ExpressionNode*); // ... protected: CodeGenerator(Bytecodestream&); protected: Bytecodestream& _output; }; // ProgramNode的每个子类在实现Traverse时,对它的ProgramNode子对象调用Traverse。 // 每个子类依次对它的子节点做同样的动作,这样一直递归下去。例如,ExpressionNode像这样定义Traverse: void ExpressionNode::Traverse (CodeGenerator& cg) { cg.visit(this); ListIterator<ProgramNode*> i(_children); for (i.First(); !i.IsDone(); i.Next()) { i.CurrentItem()->Traverse(cg); } }
// 引入Compiler类,Complier类是一个facade,它将所有部件集成在一起。Compiler提供了一个简单的接口 // 用于为特定的机器编译源代码并生成可执行代码。 class Compiler { public: Compiler(); virtual void Compile(istream&, Bytecodestream&); }; void Compiler::Compile(istream& input, Bytecodestream& output) { Scanner scanner(input); ProgramNodeBuilder builder; Parser parser; parser.Parse(scanner, builder); RISCCodeGenerator generator(output); ProgramNode* parseTree = builder.GetRootNode(); parseTree->Traverse(generator); }
6、总结
外观模式为用户提供了一个高层接口,屏蔽了多个子系统的复杂的处理逻辑。用户仅需使用外观类提供的高层接口就能实现需求,而不必亲自对各个子系统进行复杂处理。
外观模式实现了子系统与客户之间的松耦合关系,子系统的功能变化不会影响到客户。
当客户需要自己定制行为时,才需要越过Facade层,直接访问子系统。对于不需定制子系统的用户,直接使用facade提供的高层接口就可实现需求。
标签:外观,ProgramNode,Scanner,--,void,Traverse,virtual,子系统,结构型 来源: https://www.cnblogs.com/hjx168/p/16217935.html