您的位置:首页 > 其它

设计模式之外观(Facade)---对象结构型模式

2005-07-21 12:28 796 查看
设计模式之外观(Facade)---对象结构型模式(学习设计模设笔记)

1.意图
为子系统中的一组接口提供一个一致的界面,facade 模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
2.动机
将一个系统划分为若干个子系统有利于降低系统的复杂性.一个常见的设计目标是使子系统的通信和相互依赖关系达到最小,达到该目标的途径之一是引入一个外观(Facade) 对象,它为子系统中较一般的设施提供一个单一而简单的界面.
3.适用性
1)当你要为一个复杂子系统提供一个简单接口时。子系统往往因为不断演化而变得越来越复杂。大多数模式使用时都会产生更多更小的类。这使得子系统更具可重用性,也更容易对子系统进行定制,但这也给那些不需要定制子系统的用户带来一些使用上的困难。Facade 可以提供一个简单的缺省视图,这一视图对大多数用户来说已经足够,而那些需要更多的可定制性的用户可以越过Facade 层。
2)客户程序与抽象类的实现部分之间存在着很大的依赖性。引入F acade将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。
3)当你需要构建一个层次结构的子系统时,使用Facade 模式定义子系统中每层的入口点。如果子系统之间是相互依赖的,你可以让它们仅通过Facade 进行通讯,从而简化了它们之间的依赖关系。

4.结构



5.参与者
*Facade
---知道哪些子系统类负责处理请求.
---将客户的请求代理给适当的子系统对象.
*SubSysem classes
---实现子系统功能
---处理由Facade对象指派的任务.
---没有Fadede的任何相关信息.

6.协作
1)客户程序通过发送请求给Facade的方式与子系统通信,Facade模式本身必须将他的接口转换成子系统的接口.
2)使用Facade的客户趁故乡不需要访问子系统对象.
7.代码示例
/*-----------------------------------------------------
说明: 次例子是编译器的例子,看不大懂.不过可以简单理解一下Facade模式.
1) 对应关系:
Facade-----Compiler
SubSystemClasses----Scanner,Parser,ProgramNode...
/*
*/
#include "Foundation.H"
class istream;
class ostream;
class Token;
class ProgramNodeBuilder;
class ProgramNode;
class StatementNode;
class ExpressionNode;
class CodeGenerator;
class BytecodeStream;
/*
*/
class Scanner {
public:
Scanner(istream&);
virtual ~Scanner();
virtual Token& Scan();
private:
istream& _inputStream;
};
/*
*/
class Parser {
public:
Parser();
virtual ~Parser();
virtual void Parse(Scanner&, ProgramNodeBuilder&);
};
/*
*/
class ProgramNodeBuilder {
public:
ProgramNodeBuilder();
/*
*/
virtual ProgramNode* NewVariable(
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;
};
/*
*/
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();
};
/*
*/
class CodeGenerator {
public:
virtual void Visit(StatementNode*);
virtual void Visit(ExpressionNode*);
// ...
protected:
CodeGenerator(BytecodeStream&);
protected:
BytecodeStream& _output;
};
/*
*/
class ExpressionNode : public ProgramNode {
public:
ExpressionNode();
virtual void GetSourcePosition(int& line, int& index);
virtual void Add(ProgramNode*);
virtual void Remove(ProgramNode*);
virtual void Traverse(CodeGenerator&);
protected:
List<ProgramNode*>* _children;
};
/*
*/
void ExpressionNode::Traverse (CodeGenerator& cg) {
cg.Visit(this);
ListIterator<ProgramNode*> i(_children);
for (i.First(); !i.IsDone(); i.Next()) {
i.CurrentItem()->Traverse(cg);
}
}
/*
*/
class Compiler {
public:
Compiler();
virtual void Compile(istream&, BytecodeStream&);
};
/*
*/
class RISCCodeGenerator : public CodeGenerator {
public:
RISCCodeGenerator(BytecodeStream&);
virtual void Visit(StatementNode*);
virtual void Visit(ExpressionNode*);
// ...
};
/*
*/
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);
}
/*
*/
*--------------------------------------------------------*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: