资讯详情

GoF设计模式-Builder(创造者)

简介

定义

一个复杂的对象与其分离使相同的施工过程能够创建不同的表示。

类图

Director Builder builder Director(Builder builder) construct() : void Product partA PartA partB PartB setPartA(a :PartA) : void setPartB(b :PartB) : void «abstract» Builder Product product buildPartA() : void buildPartB() : void getResult() : Product ConcreteBuilderA ConcreteBuilderB

例子

理论上的一个例子

#include <iostream>

struct Product { 
        
    std::string name;
    float price;
    void show()
    { 
        
        std::cout << "name:"<<name<<"; price:"<<price<<std::endl;
    }
};

class Builder
{ 
        
    friend class Director;
protected:
    Product* product_;
    Builder():product_(new Product) { 
        }
    virtual void build_name() = 0;
    virtual void build_price() = 0;
public:
    virtual ~Builder()
    { 
        
        delete product_;
    }
    Product* GetResult() const
    { 
        
        return product_;
    }
};

class ConcreteBuilder : public Builder
{ 
        

public:
    ConcreteBuilder():Builder() { 
        }
protected:
    void build_name() override
    { 
        
        product_->name = "knife";
    }
    void build_price() override
    { 
        
        product_->price=13.85f;
    }
};

class Director
{ 
        
    Builder* builder_;
public:
    Director(Builder* const builder):builder_(builder) { 
        }
    void construct()
    { 
        
        if(!builder_)return;
        builder_->build_name();
        builder_->build_price();
    }
};

int main()
{ 
        
    ConcreteBuilder builder;
    Director director(&builder);
    director.construct();
    auto prod = builder.GetResult();
    prod->show();
    return 0;
}

c++ stringstream

实际工程中并没有像理论上这样使用创造者模式 实际开发中只用到了建造者模式注重零部件的组装过程 像是java有 java.lang.StringBuilder 中的建造者模式 java.lang.StringBuffer 中的建造者方法 Google Guava 中的建造者模式 mybatis 中的建造者模式 c++举一stringstream建造string的例子

#include <iostream>
#include <sstream>

int main()
{ 
        
    std::stringstream ss;
    ss << 100 << " " << 3.14f << " " << std::boolalpha << true << std::endl;
    std::string s = ss.str();
    std::cout << s << std::endl;
    return 0;
}

实际工程中使用builder

一般情况下,我们更习惯使用内部类及链式调用的方式实现建造者模式,即一个产品类内部自动带有一个具体建造者,由它负责该产品的组装创建,不再需要 Builder 和 Director。这样做可以使产品表示与创建之间的联系更加紧密,结构更加紧凑,同时使得建造者模式更加简洁。

#include <iostream>
#include <sstream>
#include <memory>

class Course
{ 
        
    std::string name;
    float grade;
public:
    using Pointer = std::shared_ptr<Course>;
public:
    std::string str()
    { 
        
        std::stringstream ss;
        ss << "{name:[" << name << "];grade:["<<grade<<"]}";
        return ss.str();
    }
public:
    class Builder
    { 
        
        Course* course;
    public:
        Builder():course(new Course()) { 
        }
        virtual ~Builder()
        { 
        
            delete course;
            course = nullptr;
        }
        Builder& set_name(const std::string& name)
        { 
        
            course->name = name;
            return *this;
        }
        Builder& set_grade(const float& grade)
        { 
        
            course->grade=grade;
            return *this;
        }
        Course::Pointer build()
        { 
        
            return std::make_shared<Course>(*course);
        }
    };
    inline static Builder Builder;
};
int main()
{ 
        
    auto course = Course::Builder.set_name("math").set_grade(103.0f).build();
    std::cout << course->str() << std::endl;
    auto course2 = Course::Builder.build();
    std::cout <<course2->str() << std::endl;
    return 0;
}

也可以更加c++风格一点

#include <iostream>
#include <sstream>
#include <memory>

class Course
{ 
        
    std::string name;
    float grade;
public:
    using Pointer = std::shared_ptr<Course>;
public:
    class Builder
    { 
        
        Course* course;
    public:
        Builder():course(new Course()) { 
        }
        virtual ~Builder()
        { 
        
            delete course;
            course = nullptr;
        }
        Builder& operator << (const std::string& name)
        { 
        
            course->name = name;
            return *this;
        }
        Builder& operator << (const float& grade)
        { 
        
            course->grade=grade;
            return *this;
        }
        Course::Pointer build()
        { 
        
            return std::make_shared<Course>(*course);
        }
    };
public:
    friend std::ostream& operator<<(std::ostream& out,const Course::Pointer& course);
    friend std::ostream& operator<<(std::ostream& out,const Course* const course);
    friend std::ostream& operator<<(std::ostream& out,const Course& course);
};

std::ostream& operator<<(std::ostream& out,const Course& course)
{ 
        
    out << "Course{name:[" << course.name << "];grade:["<<course.grade<<"]}";
    return out;
}

std::ostream& operator<<(std::ostream& out,const Course* const course)
{ 
        
    if (course == nullptr) return out << "nullptr";
    return out << *course;
}
std::ostream& operator<<(std::ostream& out,const Course::Pointer& course)
{ 
        
    return out << course.get();
}

int main()
{ 
        
    Course::Builder builder;
    builder << "cplusplus" << 118.5f;
    auto couse1 = builder.build();
    std::cout << couse1 << std::endl;
    return 0;
}

标签: sl6脚3a4100继电器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台