前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >生成器模式(Builder)

生成器模式(Builder)

作者头像
Florian
发布2018-02-05 11:34:15
5850
发布2018-02-05 11:34:15
举报
文章被收录于专栏:技术点滴技术点滴

生成器模式(Builder)

生成器模式(Builder)

意图:将一个对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示。

应用:编译器词法分析器指导生成抽象语法树、构造迷宫等。

模式结构

心得

和工厂模式不同的是,Builder模式需要详细的指导产品的生产。指导者(Director)使用Construct方法构造产品BuilderProduct,但是它不直接参与构造过程,而是把构造的任务交给生成器(Builder)。Builder提供了产品每一个部件构造的实现方法(可以是默认实现),但是如果要获得最终的产品,需要派生Builder的子类,添加getResult方法返回最终的产品对象。BuildPart方法正是被指导者调用指挥产品生产流程的接口。

举例

编译器中词法分析器为语法分析器提供基本的词法记号,这时可以将词法分析器看作一个指导者(Director),语法分析是为了获得一个语法树。词法分析器每次识别出一个词法结构时都会通知语法分析器,要求它做相应的语法结构匹配,直至最后生成最终的抽象语法树。这里使用一个简单词法分析的例子来说明Builder模式的实现:

代码语言:js
复制
//生成器接口
class Builder
{
protected:
    Builder(){}
public:
 virtual void addIntToken(){}
 virtual void addIdentToken(){}
 virtual void addSemiconToken(){}
 virtual ~Builder(){}
};
//抽象语法树
class Tree
{
public:
 void addNode(char*p)
    {
        cout<<"添加了一个"<<p<<"节点"<<endl;
    }
 void display()
    {
        cout<<"一颗完整的语法树"<<endl;
    }
};
//抽象语法树生成器
class SemanticTreeBuilder:public Builder
{
    Tree tree;
public:
    SemanticTreeBuilder(){}
 virtual void addIntToken()
    {
        tree.addNode("<Int>");
    }    
 virtual void addIdentToken()
    {
        tree.addNode("<标识符>");
    }
 virtual void addSemiconToken()
    {
        tree.addNode("<分号>");
    }
    Tree getTree()
    {
 return tree;
    }
};
//标识符个数生成器
class IdentCountBuilder:public Builder
{
 int num;
public:
    IdentCountBuilder():num(0){}
 virtual void addIdentToken()
    {
        num++;
    }
 int getIdCount()
    {
 return num;
    }
};
//词法分析器
class Parser
{
public:
 //使用生成器生成对象
 void Conctruct(Builder*builder)
    {
        builder->addIntToken();
        builder->addIdentToken();
        builder->addSemiconToken();
    }
};

这里构造了两个生成器,一个用来生成抽象语法树,一个用来统计标识符的个数【先不考虑实际意义】。它们重写了标准接口定义的函数,并提供了自身的实现。前者返回抽象语法树对象,后者返回标识符个数。用户使用代码形式具有一致性和简洁性:

代码语言:js
复制
Parser par;//词法分析器
SemanticTreeBuilder treeBuilder;//语法树生成器
par.Conctruct(&treeBuilder);//构造语法树
Tree tree=treeBuilder.getTree();//获取构造的语法树
tree.display();//显示语法树
IdentCountBuilder idBuilder;//标识符个数生成器
par.Conctruct(&idBuilder);//获取标识符个数
cout<<"标识符个数="<<idBuilder.getIdCount()<<endl;//输出个数

使用Builder模式,可以通过改变接口的调用创建同类不同的产品,也可以改变Builder子类创建完全不同类的产品,并且保证用户能控制产品生产的细节和流程。

参考文章http://blog.csdn.net/ldblog/article/details/2845591

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2012-12-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档