ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

结构型模式--外观

2022-05-03 11:33:56  阅读:146  来源: 互联网

标签:外观 ProgramNode Scanner -- void Traverse virtual 子系统 结构型


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有