大话设计模式 —— 第十三章《建造者模式》C++ 代码实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34536551/article/details/89184372

目录

简介

主要作用

优点

缺点

使用场景

建造者模式与工厂模式的区别


简介


建造者(也叫生成器模式,属于创建型模式)模式:将一个复杂对象的构建过程与它的构建细节分离,使得同样的构建过程可以执行不同的表示。

首先,将复杂对象的创建过程和部件的表示分离出来,其实就是把创建过程和自身的部件解耦,使得构建过程和部件都可以自由扩展,两者之间的耦合降到最低。然后,再是相同的构建过程可以创建不同的表示,相同的组合也可以通过不同的部件创建出不同的对象。


主要作用


在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象。

  • 用户只需要给出指定复杂对象的类型和内容;
  • 建造者模式负责按顺序创建复杂对象(把内部的建造过程和细节隐藏起来)

UML 图
  • 产品类(Product):一般是一个较为复杂的对象,也就是说创建对象的过程比较复杂,一般会有比较多的代码量。具体建造者要构造的复杂对象,在本类图中,产品类是一个具体的类,而非抽象类。实际编程中,产品类可以是由一个抽象类与它的不同实现组成,也可以是由多个抽象类与他们的实现组成。
  • 抽象建造者(Bulider):抽象生成器是一个接口,将建造的具体过程交与它的子类来实现。这样更容易扩展。一般至少会有两个抽象方法,一个用来建造产品,一个返回Product对象的方法;
  • 具体建造者(ConcreteProduct):实现Builder接口的类,具体建造者将实现Builder接口所定义的方法;
  • 指挥者(Director):指挥者是一个类,该类需要含有Builder接口声明的变量。指挥者的职责是负责向用户提供具体建造者的类型,即指挥者将请求具体建造者类来构造用户所需要的Product对象,如果所请求的具体建造者成功地构造出Product对象,指挥者就可以让该具体建造者返回所构造的Product对象。

C++ 代码实现 大话设计模式本章代码:

#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;

//Product Class,产品类,由多个部件组成。
class Product
{
private:
	vector<string> parts;
public:
	//添加产品部件
	void Add(string part)
	{
		parts.push_back(part);
	}
	//显示所有的产品部件
	void Show()
	{
		std::cout << "产品  创建------" << std::endl;
		for_each(parts.cbegin(), parts.cend(), [](const string &s) {cout << s << " "; });
		cout << endl;
	}
};

//Builder,抽象建造者,并声明一个得到产品建造后结果的方法GetResult。
class Builder
{
public:
	virtual ~Builder() = default;
	virtual void BuildPartA() = 0;
	virtual void BuildPartB() = 0;
	virtual Product* GetResult() = 0;
};


//ConcreteBuilder1,具体建造者类,实现Builder接口中的具体方法。
class ConcreteBuilder1 :public Builder
{
private:
	Product* product = new Product;
public:
	void BuildPartA()override
	{
		product->Add("部件A");
	}
	void BuildPartB()override
	{
		product->Add("部件B");
	}
	Product* GetResult()override
	{
		return product;
	}
};

//ConcreteBuilder2,具体建造者类,实现Builder接口中的具体方法。
class ConcreteBuilder2 :public Builder
{
private:
	Product* product = new Product;
public:
	void BuildPartA()override
	{
		product->Add("部件X");
	}
	void BuildPartB()override
	{
		product->Add("部件Y");
	}
	Product* GetResult()override
	{
		return product;
	}
};

class Director //  指挥者类,指挥建造Product的过程(控制构建各部分组件的顺序)。
{
public:
	void Construct(  Builder *const b)
	{
		b->BuildPartA();
		b->BuildPartB();
	}
};


int main()
{//用户并不需要知道具体的建造过程,只需指定建造 Product 具体类型。
	Director director;
	Builder *b1 = new ConcreteBuilder1;
	Builder *b2 = new ConcreteBuilder2;

	cout << "用ConcreteBuilder1的方法建造产品:" << endl;
	director.Construct(b1);
	Product *p1 = b1->GetResult();
	p1->Show();
	cout << endl;

	cout << "用ConcreteBuilder2的方法建造产品:" << endl;
	director.Construct(b2);
	Product *p2 = b2->GetResult();
	p2->Show();
	cout << endl;

	delete p2;
	delete p1;
	delete b1;
	delete b2;
	p2 = p1 = nullptr;
	b1 = b2 = nullptr;
	system("pause");
	return 0;
}

运行后截图:


优点


  • 建造者隐藏了该对象是如何组装的, 所以需要改变一个产品的的内部表示时,只需要在定义一个新的具体的建造者就可以了,不必修改指挥者的代码,即该模式满足开-闭原则。
  •  建造者模式的封装性很好。使用建造者模式可以有效的封装变化,在使用建造者模式的场景中,一般产品类和具体的建造者类是比较稳定的,因此,将主要的业务逻辑封装在建造者类中对整体而言可以取得比较好的稳定性。
  •   其次,建造者模式很容易进行扩展。如果有新的需求,通过实现一个新的建造者类就可以完成,基本上不用修改之前已经测试通过的代码,因此也就不会对原有功能引入风险。
  • 使用建造者模式可以使客户端不必知道产品内部组成的细节。
  • 由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。
  • 建造者模式将对象的构造过程封装在具体建造者中,用户使用不同的具体建造者就可以得到该对象的不同表示。
  • 可以更加精细有效地控制对象的构造过程。建造者将对象的构造过程分解成若干个步骤,这就使程序可以更加精细,有效地控制整个对象的构造。

易于解耦 

  • 将产品本身与产品创建过程进行解耦,可以使用相同的创建过程来得到不同的产品。也就说细节依赖抽象。

​​​​​​​缺点


  • 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
  • 会产生多余的Builder对象,可能还有Director对象,占用内存

使用场景


  • 创建一些复杂的对象, 这些对象内部构建间的建造顺序通常是稳定的, 但对象内部的构建通常面临着复杂的变化
  • 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
  • 需要生成的产品对象有复杂的内部结构,这些产品对象具备共性;

建造者模式与工厂模式的区别


  • 建造者模式与工厂模式是极为相似的,总体上,建造者模式仅仅只比工厂模式多了一个“ 指挥者 ”的 角色。在建造者模式的类图中,假如把这个指挥者看做是最终调用的客户端,那么图中剩余的部分就可以看作是一个简单的工厂模式了。
  •        与工厂模式相比,建造者模式一般用来创建更为复杂的对象,因为对象的创建过程更为复杂,因此将对象的创建过程独立出来组成一个新的类——指挥者类。也就是说,工厂模式是将对象的全部创建过程封装在工厂类中,由工厂类向客户端提供最终的产品;而建造者模式中,建造者类一般只提供产品类中各个组件的建造,而将具体建造过程交付给指挥者类。由导演类负责将各个组件按照特定的规则组建为产品,然后将组建好的产品交付给客户端。

总结

       建造者模式与工厂模式类似,他们都是建造者模式,适用的场景也很相似。一般来说,如果产品的建造很复杂,那么请用工厂模式;如果产品的建造更复杂,那么请用建造者模式。

猜你喜欢

转载自blog.csdn.net/qq_34536551/article/details/89184372