面试必备之建造者模式

一、定义

    GOF定义:将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。
    Builder模式也叫
建造者模式或者生成器模式
,是由GoF提出的23种设计模式中的一种。Builder模式是一种对象创建型模式之一,用来隐藏复合对象的创建过程,它把复合对象的创建过程加以抽象,通过子类继承和重载的方式,动态地创建具有复合属性的对象。
    例如,计算机是由 CPU、主板、内存、硬盘、显卡、机箱、显示器、键盘、鼠标等部件组装而成的,采购员不可能自己去组装计算机,而是将计算机的配置要求告诉计算机销售公司,计算机销售公司安排技术人员去组装计算机,然后再交给要买计算机的采购员。
    这些产品都是由多个部件构成的,各个部件可以灵活选择,但其创建步骤都大同小异,即产品的组成部分是不变的,但每一部分是可以灵活选择的。这类产品的创建无法用前面介绍的工厂模式描述,只有建造者模式可以很好地描述该类产品的创建。

二、角色

1.建造者(Builder):
    为创建一个产品对象的各个部件指定抽象接口。
2.具体建造者(ConcreteBuilder):
    实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并提供一个检索产品的接口。
3.指挥者(Director):
    指挥并构造一个使用Builder接口的对象。
4. 产品(Product):
    表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

    ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

UML类图如下:
在这里插入图片描述

三、实现

#include<iostream>
using namespace std;

//具体产品,房子,由门、窗、墙等组成。
class House{
    
    
private:
	string m_door;
	string m_window;
	string m_wall;
public:
	void setDoor(string door){
    
    
		this->m_door = door;
	}
	void setWindow(string window){
    
    
		this->m_window = window;
	}
	void setWall(string wall){
    
    
		this->m_wall = wall;
	}
	string getDoor(){
    
    
		cout<<this->m_door.c_str()<<endl;
		return this->m_door;
	}
	string getWindow(){
    
    
		cout<<this->m_window.c_str()<<endl;
		return this->m_window;
	}
	string getWall(){
    
    
		cout<<this->m_wall.c_str()<<endl;
		return this->m_wall;
	}
};

//Builder,提供构建房子各个组件的接口
class Builder{
    
    
public:
	virtual void builderDoor() = 0;
	virtual void builderWindow() = 0 ; 
	virtual void builderWall() = 0 ;
	virtual House* getHouse() = 0 ;
};

//指挥者,调用具体建造者构造具体的产品,和用户直接交互,使用户不用具体知道产品的实现细节。
class Director{
    
    
public:
	Director(){
    
    

	}
	void construct(Builder *builder){
    
    
		builder->builderDoor();
		builder->builderWindow();
		builder->builderWall();
	}
};

//具体建造者,对对象各部件进行设置
//建造公寓
class FlatBuilder:public Builder{
    
    
private:
	House* m_house;
public:
	FlatBuilder(){
    
    
		this->m_house = new House;
	}
	void builderDoor(){
    
    
		this->m_house->setDoor("flat door");
	}
	void builderWindow(){
    
    
		this->m_house->setWindow("flat window");
	}
	void builderWall(){
    
    
		this->m_house->setWall("flat wall");
	}
	House* getHouse(){
    
    
		return this->m_house;
	}
};
//建造别墅
class VillaBuilder:public Builder{
    
    
private:
	House* m_house;
public:
	VillaBuilder(){
    
    
		this->m_house = new House;
	}
	void builderDoor(){
    
    
		this->m_house->setDoor("valli door");
	}
	void builderWindow(){
    
    
		this->m_house->setWindow("valli window");
	}
	void builderWall(){
    
    
		this->m_house->setWall("valli wall");
	}
	House* getHouse(){
    
    
		return this->m_house;
	}
};
int main(){
    
    

	House *house = nullptr;
	Builder *builder = nullptr;
	Director *director = nullptr;

	//创建指挥者
	director = new Director();

	//client将建造房子的事交给指挥者,完全不用知晓怎样建造
	builder = new FlatBuilder();
	director->construct(builder);

	//建造好,交付房子
	house = builder->getHouse();
	house->getDoor();
	house->getWindow();
	house->getWall();
	delete house;
	delete builder;
	
	builder = new VillaBuilder();
	director->construct(builder);
	house = builder->getHouse();
	house->getDoor();
	house->getWindow();
	house->getWall();
	
	delete house;
	delete builder;

	delete director;
	return 0 ;
}

四、优缺点

主要优点如下:
各个具体的建造者相互独立,有利于系统的扩展。
客户端不必知道产品内部组成的细节,便于控制细节风险。

缺点如下:
产品的组成部分必须相同,这限制了其使用范围。
如果产品的内部变化复杂,该模式会增加很多的建造者类。

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

Factory模式:
1、有一个抽象的工厂。
2、实现一个具体的工厂—汽车工厂。
3、A工厂生产汽车A,得到汽车产品A。
4、B工厂生产汽车B,得到汽车产品B。
这样做,实现了购买者和生产线的隔离。强调的是结果。

Builder模式:
1、引擎工厂生产引擎产品,得到汽车部件A。
2、轮胎工厂生产轮子产品,得到汽车部件B。
3、底盘工厂生产车身产品,得到汽车部件C。
4、将这些部件放到一起,形成刚好能够组装成一辆汽车的整体。
5、将这个整体送到汽车组装工厂,得到一个汽车产品。
这样做,目的是为了实现复杂对象生产线和其部件的解耦。强调的是过程

两者的区别在于:
Factory模式不考虑对象的组装过程,而直接生成一个我想要的对象。
Builder模式先一个个的创建对象的每一个部件,再统一组装成一个对象。
Factory模式所解决的问题是,工厂生产产品。
而Builder模式所解决的问题是工厂控制产品生成器组装各个部件的过程,然后从产品生成器中得到产品。

六、应用场景

    建造者(Builder)模式创建的是复杂对象,其产品的各个部分经常面临着剧烈的变化,但将它们组合在一起的算法却相对稳定,所以它通常在以下场合使用。
    创建的对象较复杂,由多个部件构成,各部件面临着复杂的变化,但构件间的建造顺序是稳定的。创建复杂对象的算法独立于该对象的组成部分以及它们的装配方式,即产品的构建过程和最终的表示是独立的。

Guess you like

Origin blog.csdn.net/psl1234554321/article/details/106722092