建造者模式


在这里插入图片描述

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、缺点

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值