设计模式之建造者模式(C++实现)

建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。这是建造者模式的标准表达,不过看着让人迷惑,什么叫构建和表示的分离?一个对象使用构造函数构造之后不就固定了,只有通过它方法来改变它的属性吗?而且还要同样的构建过程搞出不同的表示,怎么可能呢?多写几个构造函数?

其实多写几个构造函数,根据不同参数设置对象不同的属性,也可以达到这样的效果,只是这样就非常麻烦了,每次要增加一种表示就要添加一个构造函数,将来构造函数会多得连自己都不记得了,这违背了开放-封闭的原则。

要不就只能设计几个set函数,每次属性不一样了,我就构造一个对象,然后用set函数改变对象的属性。这样也可以达到效果。只是代码就会非常冗余了,每个要用到这个对象的地方,都要写上好几句语句,一旦对象有点什么变化,还得到处都改一遍,这样就很容易出错,以后别人看着这种神逻辑和神代码估计也会崩溃了。而且这也违背了依赖倒转的原则。

于是大神们就开始想了,不能加很多构造函数,也不能直接用一堆set函数,然后发现,有些对象的构建是固定的几个步骤的,就像一条流水线一样,任何的产品都是通过每一个固定的步骤拼凑出来的。例如说一部手机,先放主板,再放屏幕,再放电池,再放外壳,贴个膜就能卖几千了,每次推出新产品,就换个更好的主板,换个大点的屏幕,再整个大容量电池,贴个超牛B的高透膜,又能卖出个新价钱。就是说,这些步骤都没有变,变的只是每个部分的东西。

这就是大神的厉害之处了,透过现象看本质,基本有变的,有不变的,那敢情好,面向对象的一个重要指导思想就是,封装隔离变化的,留出不变的。于是他们就用一个Builder类把步骤中的每个部分封装起来,这个类的主要作用就是生产每个部件,再抽象一下提升高度,这样就依赖倒转了,这样每次只需要添加一个类,这个类还是这几个部分,只是内部的实现已经不一样了,这样就满足了开放-封闭的原则了。但还是有一个问题,光有Builder类还不行,虽然产品的每个部分都有对应的函数,但是用起来的话,还是跟前面说的set函数一样,一用就要使用一大堆函数,也就是这变的东西是封装起来了,但这不变的东西还没留出来。这时,就添加一个Director类,这个类就是专门规定组装产品的步骤的,这样只要告诉Director使用哪个Builder,就能生产出不同的产品,对于客户端来说,只看到用了Director的一个construct函数,甚是方便。

再反过来看建造者模式的定义,构建指的就是生产一个产品的步骤,表示就是每个产品部分的具体实现,通过Director封装步骤,通过Builder封装产品部分的实现,再把他两隔离开,就能隔离变的,留出不变的供客户端使用。

优点

1.隔离了构建的步骤和具体的实现,为产品的具体实现提供了灵活度。

2.封装和抽象了每个步骤的实现,实现了依赖倒转原则。

3.封装了具体的步骤,减少了代码的冗余。

 

缺点

1.要求构建产品的步骤(算法)是不能剧烈变化的,最好是不变的,这样就影响了灵活度。


代码如下

/**********************************AbstractBuilder.h**************************************/

#include <iostream>
using namespace std;
#pragma once;
class AbstractBuilder
{
public:
	AbstractBuilder(){};
	~AbstractBuilder(){};
	virtual void BuilderHead(string) = 0;
	virtual void BuilderBody(string) = 0;
	virtual void BuilderHand(string) = 0;
	virtual void BuilderFoot(string) = 0;
};
/*************************************Builder.h******************************************/

#include "AbstractBuilder.h"
#include "Product.h"
#pragma once;
class Builder : public AbstractBuilder
{
private:
	Product * myProduct;
public:
	Builder(Product * product){
		myProduct = product;
	};
	~Builder(){};
	void BuilderHead(string head)
	{
		myProduct->SetHead(head);
	};
	void BuilderBody(string body)
	{
		myProduct->SetBody(body);
	};
	void BuilderHand(string hand)
	{
		myProduct->SetHand(hand);
	};
	void BuilderFoot(string foot)
	{
		myProduct->SetFoot(foot);
	};
};

/*************************************Product.h*****************************************/

#include <iostream>
#include <string>
using namespace std;
#pragma once;

class Product
{
private:
	string head;
	string body;
	string hand;
	string foot;
public:
	Product(){};
	~Product(){};
	void SetHead(string head){
		this->head = head;
	}
	void SetBody(string body){
		this->body = body;
	}
	void SetHand(string hand){
		this->hand = hand;
	}
	void SetFoot(string foot){
		this->foot = foot;
	}
	void show()
	{
		cout<<"创建的人物为"<<head<<" "<<body<<" "<<hand<<" "<<foot<<endl;
	}
};

/*************************************Director.h*****************************************/

#include "Builder.h"
//#include "AbstractBuilder.h"
#pragma once;
class Director
{
	AbstractBuilder * builder;
public:
	Director(AbstractBuilder * builder)
	{
		this->builder = builder;
	};
	~Director(){};
	void construct()
	{
		builder->BuilderHead("大头");
		builder->BuilderBody("瘦身");
		builder->BuilderHand("细手");
		builder->BuilderFoot("长腿");
	}
};

/*************************************main.cpp*****************************************/

#include "Builder.h"
#include "Director.h"

int main()
{
	Product * product = new Product;
	AbstractBuilder * builder = new Builder(product);
	Director * director = new Director(builder);
	director->construct();
	product->show();
	getchar();
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值