C++设计模式-Builder建造者模式
作用:
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
Builder模式和AbstractFactory模式在功能上很相似,因为都是用来创建大的复杂的对象,它们的区别是:Builder模式强调的是一步步创建对象,并通过相同的创建过程可以获得不同的结果对象,一般来说Builder模式中对象不是直接返回的。而在AbstractFactory模式中对象是直接返回的,AbstractFactory模式强调的是为创建多个相互依赖的对象提供一个同一的接口。
适用于以下情况:
1)当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
2)当构造过程必须允许被构造的对象有不同的表示时。
UML图如下:
Builder:定义创建对象过程的抽象,提供构建不同组成部分的接口
其中:BuildPartA,BuildPartB,BuildPartC是对一个对象不同部分的构建函数接口,由Builder的派生类ConcreteBuilder1、ConcreteBuilder2来具体实现.
另外还有一个需要注意的函数,就是Director::Construct函数,这个函数里面通过调用上面的接口函数完成对象的构建--也就是说各个不同部分装配的过程都是一致的(同样的调用的Construct函数),但是不同的构建方式会有不同的表示(根据Builder的实际类型来决定如何构建,也就是多态)
Builder模式是基于这样的一个情况:一个对象可能有不同的组成部分,这几个部分的不同的创建对象会有不同的表示,但是各个部分之间装配的方式是一致的.比方说一辆单车,都是由车轮车座等等的构成的(一个对象不同的组成部分),不同的品牌生产出来的也不一样(不同的构建方式).虽然不同的品牌构建出来的单车不同,但是构建的过程还是一样的
也就是说,Director::Construct函数中固定了各个组成部分的装配方式,而具体是装配怎样的组成部分由Builder的派生类实现.
实现:
Builder模式的实现基于以下几个面向对象的设计原则:
1)把变化的部分提取出来形成一个基类和对应的接口函数,在这里不会变化的是都会创建PartA和PartB,变化的则是不同的创建方法,于是就抽取出这里的Builder基类和BuildPartA,BuildPartB接口函数
2)采用聚合的方式聚合了会发生变化的基类,就是这里Director聚合了Builder类的指针.
以上,通过两个派生类ConcreteBuilder1、ConcreteBuilder2定义了两种不同的建造细节(建造步骤是一样的,由Construct函数确定),通过两个派生类所建造出来的对象,对外部所展现出来的属性或者功能是不一样的,由各自Builder派生类中的建造方法(BuildPartA、BuildPartB、BuildPartC)决定。
代码如下:
Builder.h
#ifndef _BUILDER_H_
#define _BUILDER_H_ #include <string>
#include <vector> using namespace std; //产品类
class Product
{
private:
string m_partA;
string m_partB;
string m_partC;
public:
void setPartA(const string& s);
void setPartB(const string& s);
void setPartC(const string& s);
Product();
~Product();
}; //抽象Builder基类,定义不同部分的创建接口
class Builder
{
public:
virtual void BuildPartA()=;
virtual void BuildPartB()=;
virtual void BuildPartC()=;
virtual Product* GetProduct()=;
Builder();
virtual ~Builder();
}; // Builder的派生类,实现BuilderPartA和BuilderPartB和BuildPartC接口函数
class ConcreteBuilder1:public Builder
{
public:
ConcreteBuilder1();
~ConcreteBuilder1();
virtual void BuildPartA();
virtual void BuildPartB();
virtual void BuildPartC();
virtual Product* GetProduct();
private:
Product* m_pProduct;
}; // Builder的派生类,实现BuilderPartA和BuilderPartB和BuildPartC接口函数
class ConcreteBuilder2:public Builder
{
public:
ConcreteBuilder2();
~ConcreteBuilder2();
virtual void BuildPartA();
virtual void BuildPartB();
virtual void BuildPartC();
virtual Product* GetProduct();
private:
Product* m_pProduct;
}; //ConcreteBuilder1与ConcreteBuilder2是Builder的两个派生类,用于实现两种不同的建造细节 // 使用Builder构建产品,构建产品的过程都一致,但是不同的builder有不同的实现
// 这个不同的实现通过不同的Builder派生类来实现,存有一个Builder的指针,通过这个来实现多态调用
class Director
{
public:
Director(Builder* pBuilder);
~Director(); //Construct函数定义一个对象的整个构建过程,不同的部分之间的装配方式都是一致的,
//首先构建PartA其次是PartB,只是根据不同的构建者会有不同的表示
void Construct();
//void Construct(const string& buildPara);
private:
Builder* m_pBuilder;
}; #endif
Director.cpp
#include "Builder.h"
#include <iostream>
#include <vector> using namespace std; Product::~Product()
{
} Product::Product()
{} void Product::setPartA(const string& s)
{
this->m_partA = s;
} void Product::setPartB(const string& s)
{
this->m_partB = s;
} void Product::setPartC(const string& s)
{
this->m_partC = s;
} Builder::Builder()
{} Builder::~Builder()
{} ConcreteBuilder1::ConcreteBuilder1()
{
this->m_pProduct = new Product();
cout<<"Create empty product!"<<endl;
} void ConcreteBuilder1::BuildPartA()
{
this->m_pProduct->setPartA("A");
cout<<"BuildPartA"<<endl;
} void ConcreteBuilder1::BuildPartB()
{
this->m_pProduct->setPartB("B");
cout<<"BuildPartB"<<endl;
} void ConcreteBuilder1::BuildPartC()
{
this->m_pProduct->setPartC("C");
cout<<"BuildPartC"<<endl;
} Product* ConcreteBuilder1::GetProduct()
{
return this->m_pProduct;
} ConcreteBuilder1::~ConcreteBuilder1()
{
delete this->m_pProduct;
this->m_pProduct = NULL;
} ConcreteBuilder2::ConcreteBuilder2()
{
this->m_pProduct = new Product();
cout<<"Create empty product!"<<endl;
} void ConcreteBuilder2::BuildPartA()
{
this->m_pProduct->setPartA("A");
cout<<"BuildPartA"<<endl;
} void ConcreteBuilder2::BuildPartB()
{
this->m_pProduct->setPartB("B");
cout<<"BuildPartB"<<endl;
} void ConcreteBuilder2::BuildPartC()
{
this->m_pProduct->setPartC("C");
cout<<"BuildPartC"<<endl;
} Product* ConcreteBuilder2::GetProduct()
{
return this->m_pProduct;
} ConcreteBuilder2::~ConcreteBuilder2()
{
delete this->m_pProduct;
this->m_pProduct = NULL;
} Director::Director(Builder* pBuilder)
{
this->m_pBuilder = pBuilder;
} void Director::Construct()
{
this->m_pBuilder->BuildPartA();
this->m_pBuilder->BuildPartB();
this->m_pBuilder->BuildPartC();
} Director::~Director()
{
delete this->m_pBuilder;
this->m_pBuilder = NULL;
}
main.cpp
#include "Builder.h"
#include <iostream> using namespace std; int main()
{
Director* pDirector = new Director(new ConcreteBuilder1());
pDirector->Construct(); Director* pDirector1 = new Director(new ConcreteBuilder2());
pDirector1->Construct(); return ;
}
建造者模式和工厂模式非常相似呀,但是记住一点你就可以游刃有余的使用了:
建造者模式最主要功能是基本方法的调用顺序安排,也就是这些基本方法已经实现了;
而工厂方法则重点是创建,你要什么对象我创造一个对象出来,组装顺序则不是他关心的。
建造者模式使用的场景,一是产品类非常的复杂,或者产品类中的调用顺序不同产生了不同的效能,这个时候使用建造者模式是非常合适
C++设计模式-Builder建造者模式的更多相关文章
- 一天一个设计模式——Builder建造者模式
		
一.模式说明 在现实世界中,当我们要构造一个大型工程时(建一个大楼),通常的做法是先建造工程的每个独立部分,然后再逐步构造完成(先打地基,再搭框架,最后逐层累造).在程序设计领域,构造一个复杂的类时( ...
 - Android设计模式——Builder(建造者)模式
		
1.建造者模式是一步一步创建一个复杂对象的创建模式.该模式是为了将构建复杂对象的过程和他的部件解耦,使得构建过程和部件表示隔离开. 2.Bulider模式的定义是:将一个复杂对象的构建与它的表示分离, ...
 - Java设计模式之建造者模式(Builder)
		
前言: 最近一直在学习okHttp,也对其做了一些整理,okHttp和Retrofit结合大大加速我们的开发效率,源码里面采用了很多设计模式,今天我们来学习一下其中的设计模式之一建造者模式. 建造者模 ...
 - C#设计模式(5)——建造者模式(Builder Pattern)
		
一.引言 在软件系统中,有时需要创建一个复杂对象,并且这个复杂对象由其各部分子对象通过一定的步骤组合而成.例如一个采购系统中,如果需要采购员去采购一批电脑时,在这个实际需求中,电脑就是一个复杂的对象, ...
 - 乐在其中设计模式(C#) - 建造者模式(Builder Pattern)
		
原文:乐在其中设计模式(C#) - 建造者模式(Builder Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 建造者模式(Builder Pattern) 作者:webabc ...
 - C#设计模式之四建造者模式(Builder Pattern)【创建型】
		
一.引言 今天我们要讲讲Builder模式,也就是建造者模式,当然也有叫生成器模式的,英文名称是Builder Pattern.在现实生活中,我们经常会遇到一些构成比较复杂的物品,比如:电脑,它就是一 ...
 - 【GOF23设计模式】建造者模式
		
来源:http://www.bjsxt.com/ 一.[GOF23设计模式]建造者模式详解类图关系 建造飞船 package com.test.Builder; public class AirShi ...
 - 折腾Java设计模式之建造者模式
		
博文原址:折腾Java设计模式之建造者模式 建造者模式 Separate the construction of a complex object from its representation, a ...
 - Java 设计模式之建造者模式(四)
		
原文地址:Java 设计模式之建造者模式(四) 博客地址:http://www.extlight.com 一.前言 今天继续介绍 Java 设计模式中的创建型模式--建造者模式.上篇设计模式的主题为 ...
 
随机推荐
- Rhel6-cacti+nagios+ganglia(nginx)配置文档
			
(lnmp平台) 系统环境: rhel6 x86_64 iptables and selinux disabled 主机: 192.168.122.185 server85.example.com 1 ...
 - [CDN]CDN的系统架构
			
---恢复内容开始--- 1.功能架构: CDN技术自1998年诞生以来,伴随着互联网的高速发展,其技术一直在持续演进和完善,但基本的CDN功能架构在2003年左右就已基本形成和稳定下来.从功能上划分 ...
 - 《大象-Think In UML》读书笔记1
			
大音希声,大象希行. 什么是面向过程?什么是面向对象? 面向过程归纳为结构化程序设计.DFD图.ER模型.UC矩阵等,而面向对象则被归纳为继承.封装.多态.复用等具体的技术.事实上,上述的所有技术都只 ...
 - JVM-class文件完全解析-属性表集合
			
属性表集合 在前面魔数,次版本号,主板本号,常量池入口,常量池,访问标志,类索引,父类索引,接口索引集合,字段表集合,方法表集合,那么接下来就是属性表集合了. 在class文件,字段表,方法表都可 ...
 - OC之160728
			
NSData与NSMutableData:代表数据缓冲区有两个作用,将数据读入NSData和输出NSData数据 输出 将字符串写入指定文件 用NSFileManager:为创建,删除,移动,复制文件 ...
 - javascript之DOM篇二(操作)
			
一.创建DOM元素 createElement:document.createElement(' 所要创建的元素标签名'): <!DOCTYPE html><html>< ...
 - Fragment的初步设计
			
Fragment的初步设计 Fragment功能 Fragment将每一段碎片时间归类到一个具体的事件上: 使用者可以创建多个事件对碎片时间进行分类: 使用者点击事件会进入用户自己设置好的事件对应的A ...
 - 根据地图上的两个点各自的x,y坐标,计算出2点之间的直线距离。显示为公里、米
			
/** * calc_map_distance() , 根据地图上的两个点各自的x,y坐标,计算出2点之间的直线距离 * @param array $point_1 第1个点的x,y坐标 array( ...
 - java中时间类型的问题
			
时间类型:System.currentTimeMillis() 获得的是自1970-1-01 00:00:00.000 到当前时刻的时间距离,类型为longimport java.sql.Date d ...
 - LoadRunner常见问题
			
1.Error -27257: Pending web_reg_save_param/reg_find/create_html_param[_ex] request(s) detected and r ...