建造者模式
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、缺点
注意区分抽象工厂模式:
建造者模式注重于对象组合,即不同的小对象组成一个整体的复杂大对象,而抽象工厂模式针对于接口编程,只是对外提供创建对象的工厂接口,不负责对象之后的处理。
上一篇: java编程思想——第十二章(通过异常处理错误)》
下一篇: H5分享页面自定义图片标题