design pattern的学习和思考(2)

来源:互联网 发布:数据录入系统 编辑:程序博客网 时间:2024/06/07 19:29

生成器(Builder)

生成器和抽象工厂非常的相似,都是用来生成对象的,生成器主要着重于一步步的创建一个复杂对象,并且在最后返回结果,而抽象工厂着重于创建一系列的对象,并且在创建后立即返回。
先看一下下面的代码

class ProductPartA
{}
class ProductPartB
{}
class ComplexProduct
{
public:
    
void AddPartA(ProductPartA* partA){ m_PartAList.push_back(partA);}
    
void AddPartB(ProductPartB* partB){ m_PartBList.push_back(partB);}
            
private:
    vector
<ProductPartA*> m_PartAList;
    vector
<ProductPartB*> m_PartBList;
}

这段代码描述了一个复杂对像ComplexProduct,它由PartA的一个list和PartB的一个list组成,要创建这样一个对象就非常适合用生成器的设计模式,我们定义一个生成器

class ComplexProductBuilder
{
public:
    
virtual void BuildProduct()
    { 
        m_Product 
= new ComplexProduct;
    }
    
virtual void BuildPartA()
    {
        ProductPartA
* partA = new ProductPartA;
        m_Product
->AddPartA(partA);
    }
    
virtual void BuildPartB()
    {
        ProductPartB
* partB = new ProductPartB;
        m_Product
->AddPartB(partB);
    }
    ComplexProduct
* GetProduct()
    {
        
return m_Product;
    }
private:
    ComplexProduct
* m_Product;
}

有了这样一个生成器,我们就可以方便的生成一个ComplexProduct,假设ComplexProduct需要包含两个PartA,一个PartB

void CreateComplexProduct(const ComplexProductBuilder* builder)
{
    builder
->BuilderProduct();
    builder
->BuilderPartA();
    builder
->BuilderPartA();
    builder
->BuilderPartB();
}

ComplexProductBuilder builder;
CreateComplexProduct(
&builder);
ComplexProduct
* p = builder.GetProduct();

可以看到,生成器帮我们全权代理了对象的整个构建过程,使其与对象的表现形式所分开,另一方面我们还可以通过继承来实现各种我们所需要的生成器,一个特殊的例子就是,我们可以通过生成器来给对象计数,再看上面的例子,如果我们需要知道PartA和PartB的个数,就可以构建一个计数的生成器来实现

class ComplexProductCountBuilder
{
public:
    
virtual void BuildProduct()
    { 
        m_PartACnt 
= 0;
        m_PartBCnt 
= 0;
    }
    
virtual void BuildPartA()
    {
        m_PartACnt
++;
    }
    
virtual void BuildPartB()
    {
        m_PartBCnt
++;
    }
    
int GetPartACnt(){ return m_PartACnt;    }
    
int GetPartBCnt(){ return m_PartBCnt;    }
private:
    
int m_PartACnt;
    
int m_PartBCnt;
}

//调用
ComplexProductCountBuilder cntBuilder;
CreateComplexProduct(
&cntBuilder);
int PartACount = cntBuilder.GetPartACnt();
int PartBCount = cntBuilder.GetPartBCnt();

是不是非常的方便,一点也不用修改原来的代码。通常,如果一个对象是通过其他对象组合的方式得到的,就可以考虑使用生成器模式

最后给大家一张生成器的UML图来方便大家理解

 

原创粉丝点击