设计模式学习笔记(Build模式)
来源:互联网 发布:功能分析和数据分析 编辑:程序博客网 时间:2024/05/15 08:50
一、Build模式的作用
通过Build模式可以利用同一个创建过程创建出不同的对象,即同样的构建过程可以创建不同的表示。并且将具体的构建过程向客户隐藏。
Build模式的参与者有Builder、ConcreteBuild、Dirctor以及Product。构建指的就是生产一个产品的步骤(Dirctor),表示就是每个产品部分的具体实现(ConcreteBuild),通过Director封装步骤,通过Builder封装产品部分的实现[具体实现在ConcreteBuild类中],再把他两分离表示,最后被构造的复杂对象就是Product类对象(主角)。
二、为什么需要Build模式
那我们为什么不多写几个构造函数,通过不同参数创建具有不同属性的对象?
如果这样做,每次要新增一种对象的表示,我们都需要在之前的类中添加一个构造函数,从可读性和设计上来看,都非常臃肿,不符合面向对象的封闭原则。
那能不能利用对象所在类中的set函数,每次新建对象通过进行不同的set来得到具有不同属性的对象?
这样做虽然满足了封闭原则,但是却完全属于面向过程的设计,没有将对象的构建与表示分离,并且如果要设置的参数过多则不好管理。
而Build模式将一个复杂对象的构建与它的表示分离,封装和抽象了每个步骤的实现,向客户隐藏了产品内部的实现。使得可以利用同样的构建过程创建出不同的表示。
三、使用场景
建造者模式主要用于“分步骤构建一个复杂的对象”,在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。
抽象工厂模式(AbtractFactory)解决的是“系列对象”的需求变化,Builder模式解决的是“对象部分”的需求变化,建造者模式常和组合模式(Composite Pattern)结合使用。
需要隐藏产品的具体建造过程。
四、缺点
使用Builder模式是增加了代码量
五、实例
比如:将大象装进冰箱分为3步:A(打开冰箱门)、B(将大象放进去)、C(关上冰箱门)。通过A->B->C三个步骤完成将大象装进冰箱这个操作。但是问题来了,如果我们想将大象装进不同品牌不同型号的冰箱怎么办?不同品牌不同型号的冰箱也许开门的具体操作不同,关门的具体操作不同等等.....
这时,Build模式就起作用了!Dirctor表示了这三个步骤;Build类表示了每一个操作(但是没有具体的实现);ConcreteBuild是具体的实现(继承Build);
Dirctor部分:
Director.h#ifndef _DIRECTOR_H_#define _DIRECTOR_H_#include "ConcreteBuilder.h"class Director{public:Director(Builder* builder);~Director();void construct();private:Builder* curBuilder;};#endif
Director.cpp#include "Director.h"Director::Director(Builder* builder){ curBuilder = builder;}Director::~Director(){}void Director::construct(){if (!curBuilder)return;curBuilder->createProduct();curBuilder->buildPartA(1);//A(打开冰箱门)curBuilder->buildPartB(2);//B(将大象放进去)curBuilder->buildPartC(3);//C(关上冰箱门)}Build部分:[这里也可以不将Build变为纯虚类,使客户只对他们感兴趣的操作进行重定义]
class Builder{public:Builder();virtual ~Builder();virtual void createProduct() = 0;virtual void buildPartA(int param) = 0;virtual void buildPartB(int param) = 0;virtual void buildPartC(int param) = 0;virtual Product* getProduct() = 0;};ConcreteBuilder部分:每个步骤的具体实现(不同品牌不同型号冰箱的每个步骤的具体操作在这里修改)
class ConcreteBuilder: public Builder{public:ConcreteBuilder();~ConcreteBuilder();void createProduct();void buildPartA(int param);//针对不同的品牌不同的型号,可以有不同的实现(例如有的冰箱没有门,则该函数内容为空)void buildPartB(int param);void buildPartC(int param);Product* getProduct();private:Product* curProduct;};
ConcreteBuilder::ConcreteBuilder():curProduct(NULL){}ConcreteBuilder::~ConcreteBuilder(){}void ConcreteBuilder::createProduct(){cout<<"完成一个表演";curProduct = new Product();}void ConcreteBuilder::buildPartA(int param){cout<<"将A牌冰箱门打开";curProduct->setPartA(param);}void ConcreteBuilder::buildPartB(int param){cout<<"将大象装进A牌冰箱";curProduct->setPartB(param);}void ConcreteBuilder::buildPartC(int param){cout<<"将A牌冰箱门关闭\n");curProduct->setPartC(param);}Product* ConcreteBuilder::getProduct()//这里涉及到指针对象的释放问题,由于只是伪代码,不详细展开.{return curProduct;}Product
class Product{public:Product();~Product();void setPartA(int param);void setPartB(int param);void setPartC(int param);void show();private:int partA;int partB;int partC;};
Product::Product(){}Product::~Product(){}void Product::setPartA(int param){partA = param;}void Product::setPartB(int param){partB = param;}void Product::setPartC(int param){partC = param;}void Product::show(){ cout<<"partA = "<<partA<<"partB ="<<partB<<"partC = "<<partC;}
具体的调用:
int main(){Builder* builder = new ConcreteBuilder();Director* director = new Director(builder);director->construct();Product* product = builder->getProduct();product->show();return 0;}
- 设计模式学习笔记(Build模式)
- 设计模式学习笔记(二)——Build生成器
- 设计模式学习笔记(原型模式)
- 设计模式学习笔记(组合模式)
- 设计模式---观察者模式(学习笔记)
- 设计模式学习笔记(原型模式)
- 设计模式学习笔记(工厂模式)
- 设计模式(学习笔记)
- 设计模式(1)—Build模式
- 设计模式学习笔记
- 设计模式学习笔记
- 设计模式学习笔记
- 设计模式【学习笔记】
- 设计模式 学习笔记
- 设计模式学习笔记
- 设计模式学习笔记
- 设计模式学习笔记
- 设计模式学习笔记
- OpenCV imread读取图片失败
- 获得当前时间的几种方法
- 用js写一个简单的聊天室
- 使用友员重载运算符讨论
- [LeetCode]142. Linked List Cycle II
- 设计模式学习笔记(Build模式)
- Eclicpse 快捷键大全
- java设计模式之单例模式
- linux安装禅道(CentOS)
- hdu 6108 小C的倍数问题(同余定理)
- ccf201512-2消除类游戏
- 测试
- JavaScript原型、原型链、对象的创建
- 数据分析最常用的matplot基础使用笔记