欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

建造者模式

程序员文章站 2024-03-17 17:36:40
...


建造者模式

1、场景举例

之间提到的那个买鞋店,使用简单工厂模式、工厂方法模式、抽象工厂模式可以很完美的解决问题。但是如果细心的话,可以发现,工厂类模式比较适合那些存在相关性的场景。对象的元素之间往往存在一定的联系,最后生成单一对象。但是如果此时把买鞋店换成组装电脑,我生产一台个人电脑需要配置cpu、内存、显卡、主机这些东西,各个元素都是一个对象,且对象之间没有任何联系。这种情况下使用建造者模式更合适解决这类问题。当然,工厂模式也可以解决该问题,但是但凡问题总有最优解,不是吗?

2、主要应用场景

1、最后要生成的对象内部具有复杂的结构,生成该对象的步骤是相同的,但是每一步的具体实现可以是变化的
2、复杂对象的各个元素(子对象),之间没有相关性,可以完全分离讨论。
3、builder设计如何创建一个部件,director负责最后部件的组装。将设计和实现解耦

3、类图

建造者模式

4、用C语言实现创建者模式

角色定义

1、builder-part:实现对象元素函数实现
2、Builder:用来生产最终对象,固化对象实现步骤

案例描述

本案例实现一个简单创建者模式,本想按照C++设计一个复杂模型,但是模式是为了解决问题,不能为了模式和设计模式,因此使用创建者模式简单实现组装电脑。

案例实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct PERSONAL_COMPUTER {
	char cpu[20];
	char memory[20];
	char harddisk[20];
}Personal_Computer;


void assemble_intel_cpu(Personal_Computer* personal_computer)
{
	strncpy(personal_computer->cpu, "inter",sizeof("inter"));
	return;
}
void assemble_amd_cpu(Personal_Computer* personal_computer)
{
	strncpy(personal_computer->cpu, "amd", sizeof("amd"));
	return;
}
void assemble_samsung_memory(Personal_Computer* personal_computer)
{
	strncpy(personal_computer->memory,"samsung", sizeof("samsung"));
	return;
}
void assemble_kingston_memory(Personal_Computer* personal_computer)
{
	strncpy(personal_computer->memory, "kingston", sizeof("kingston"));
	return;
}
void assemble_hitachi_harddisk(Personal_Computer* personal_computer)
{
	strncpy(personal_computer->harddisk, "hitachi", sizeof("hitachi"));
	return;
}
void assemble_digital_harddisk(Personal_Computer* personal_computer)
{
	strncpy(personal_computer->harddisk, "digital", sizeof("digital"));
	return;
}

struct PERSONAL_COMPUTER* builder_fast_config()
{
	struct PERSONAL_COMPUTER *Personal_Computer = NULL;

	Personal_Computer = (struct PERSONAL_COMPUTER*)malloc(sizeof(struct PERSONAL_COMPUTER));
	if (Personal_Computer == NULL) {
		return NULL;
	}

	assemble_intel_cpu(Personal_Computer);
	assemble_hitachi_harddisk(Personal_Computer);
	assemble_kingston_memory(Personal_Computer);

	return Personal_Computer;
}

struct PERSONAL_COMPUTER* builder_safty_config()
{
	struct PERSONAL_COMPUTER* personal_computer = NULL;

	personal_computer = (struct PERSONAL_COMPUTER*)malloc(sizeof(struct PERSONAL_COMPUTER));
	if (personal_computer == NULL) {
		return NULL;
	}

	assemble_amd_cpu(personal_computer);
	assemble_digital_harddisk(personal_computer);
	assemble_samsung_memory(personal_computer);

	return personal_computer;
}


int main()
{
	struct PERSONAL_COMPUTER* my_personal_computer = NULL;

	my_personal_computer = builder_safty_config();

	printf("%s\n", my_personal_computer->cpu);
	printf("%s\n", my_personal_computer->memory);
	printf("%s\n", my_personal_computer->harddisk);

	if (my_personal_computer != NULL) {
		free(my_personal_computer);
	}

	return 0;
}

5、用C++实现简单工厂模式

角色定义

1、目标结构
2、目标结构类:封装给目标结构赋值函数
3、抽象builder和具体子builder:封装如何创建一个个部件
4、director:构建最后的复杂对象

案例描述

使用创建者模式描述一个人,头、身体、左手、右手、左脚、右脚的胖瘦情况

案例实现

#include <iostream>
#include <stdlib.h>
#include <string.h>

using namespace std;

typedef enum MAN_TAG {
	fat,
	thin,
	normal
}Man_Tag;

/*定义一个结构来描述一个人*/
typedef struct MAN_DESCRIBE {
	Man_Tag head;
	Man_Tag body;
	Man_Tag left_hand;
	Man_Tag right_hand;
	Man_Tag left_foot;
	Man_Tag right_foot;
}Man_Describe;

/*定义一个类*/
class MAN {
public:
	void Set_Head(enum MAN_TAG tag) { man_describe.head = tag; }
	void Set_Body(enum MAN_TAG tag) { man_describe.body = tag; }
	void Set_Left_Hand(enum MAN_TAG tag) { man_describe.left_hand = tag; }
	void Set_Right_Hand(enum MAN_TAG tag) { man_describe.right_hand = tag; }
	void Set_Left_Foot(enum MAN_TAG tag) { man_describe.left_foot = tag; }
	void Set_Right_Foot(enum MAN_TAG tag) { man_describe.right_foot = tag; }
	void make_conversion(Man_Tag , char* );

	void Show_Man() {
		char buff[12];
		make_conversion(man_describe.head, buff);
		cout << "my head is "       <<  buff<< endl;
		make_conversion(man_describe.head, buff);
		cout << "my body is "       << buff << endl;
		make_conversion(man_describe.head, buff);
		cout << "my left hand is "  << buff << endl;
		make_conversion(man_describe.head, buff);
		cout << "my right hand is " << buff << endl;
		make_conversion(man_describe.head, buff);
		cout << "my left foot is "  << buff << endl;
		make_conversion(man_describe.head, buff);
		cout << "my right foot is " << buff << endl;
	}
private:
	struct MAN_DESCRIBE man_describe;
};

void MAN::make_conversion(Man_Tag man_tag,char *buff)
{
	char sta_fat[16] = "fat";
	char sta_thin[16] = "thin";
	char sta_normal[16] = "normal";

	if (man_tag == fat) {
		strncpy(buff,"fat", sizeof(buff));
	}
	else if (man_tag == thin) {
		strncpy(buff,"thin", sizeof(buff));
	}
	else {
		strncpy(buff,"normal", sizeof(buff));
	}

	return;
}

class BUILDER {
public:
	virtual void Set_Head() = 0;
	virtual void Set_Body() = 0;
	virtual void Set_Left_Hand() = 0;
	virtual void Set_Right_Hand() = 0;
	virtual void Set_Left_Foot() = 0;
	virtual void Set_Right_Foot() = 0;
	virtual MAN* Get_Man() = 0;
};

class fat_man_builder :public BUILDER {
public:
	fat_man_builder() { fat_man = new MAN(); }
	void Set_Head() { fat_man->Set_Head(fat); }
	void Set_Body(){ fat_man->Set_Body(fat); }
	void Set_Left_Hand(enum MAN_TAG){ fat_man->Set_Left_Hand(fat); }
	void Set_Right_Hand(enum MAN_TAG){ fat_man->Set_Right_Hand(fat); }
	void Set_Left_Foot(enum MAN_TAG){ fat_man->Set_Left_Foot(fat); }
	void Set_Right_Foot(enum MAN_TAG){ fat_man->Set_Right_Foot(fat); }
	MAN* Get_Man() { return fat_man; }
private:
	MAN* fat_man;
};

class thin_man_builder :public BUILDER {
public:
	thin_man_builder() { thin_man = new MAN(); }
	void Set_Head() { thin_man->Set_Head(thin); }
	void Set_Body() { thin_man->Set_Body(thin); }
	void Set_Left_Hand() { thin_man->Set_Left_Hand(thin); }
	void Set_Right_Hand() { thin_man->Set_Right_Hand(thin); }
	void Set_Left_Foot() { thin_man->Set_Left_Foot(thin); }
	void Set_Right_Foot() { thin_man->Set_Right_Foot(thin); }
	MAN* Get_Man() { return thin_man; }
private:
	MAN* thin_man;
};

class DIRECTOR {
public:
	DIRECTOR(BUILDER* builder) { m_builder = builder; }
	void CreateMan();
private:
	BUILDER* m_builder;
};

void DIRECTOR::CreateMan()
{
	m_builder->Set_Head();
	m_builder->Set_Body();
	m_builder->Set_Left_Hand();
	m_builder->Set_Right_Hand();
	m_builder->Set_Left_Foot();
	m_builder->Set_Right_Foot();
}

int main()
{
	thin_man_builder *thin_man_build = new thin_man_builder();
	DIRECTOR* director = new DIRECTOR(thin_man_build);
	director->CreateMan();
	MAN* thin_man = thin_man_build->Get_Man();

	thin_man->Show_Man();
	
    
    delete thin_man_build;
    thin_man_build = NULL;
    
    delete director;
    director = NULL;

    delete thin_man;
    thin_man = NULL;
    
	return 0;
}

6、缺点

注意区分抽象工厂模式:
建造者模式注重于对象组合,即不同的小对象组成一个整体的复杂大对象,而抽象工厂模式针对于接口编程,只是对外提供创建对象的工厂接口,不负责对象之后的处理。

相关标签: 编程设计模式