建造者模式
C++
参考:https://www.cnblogs.com/Galesaur-wcy/p/15907863.html
#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;
return 0;
}
C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 产品部件
typedef struct Product
{
char **parts;
size_t parts_count;
} Product;
// 构建者接口
typedef struct Builder
{
void (*build_part_a)(Product *);
void (*build_part_b)(Product *);
Product *(*get_result)(void *);
} Builder;
// 具体构建者基类,用于存储产品实例
typedef struct ConcreteBuilder
{
Product product;
} ConcreteBuilder;
// 导演类
typedef struct Director
{
void (*construct)(struct Director *, Builder *, void *, Product **);
} Director;
// 初始化产品
void init_product(Product *product)
{
product->parts = NULL;
product->parts_count = 0;
}
// 释放产品
void free_product(Product *product)
{
if (product->parts != NULL)
{
int i;
for (i = 0; i < product->parts_count; ++i)
{
free(product->parts[i]);
}
free(product->parts);
}
}
// 添加部件到产品
void add_part(Product *product, const char *part)
{
product->parts = (char **)realloc(product->parts, sizeof(char *) * (product->parts_count + 1));
product->parts[product->parts_count++] = strdup(part);
}
// 展示产品部件
void show_product(Product *product)
{
printf("产品 创建:\n");
int i;
for (i = 0; i < product->parts_count; ++i)
{
printf("%s ", product->parts[i]);
}
printf("\n");
}
// 实现ConcreteBuilder1的构建方法
void build_part_a_concrete_builder1(Product *product)
{
add_part(product, "部件A");
}
void build_part_b_concrete_builder1(Product *product)
{
add_part(product, "部件B");
}
// 实现ConcreteBuilder2的构建方法
void build_part_a_concrete_builder2(Product *product)
{
add_part(product, "部件X");
}
void build_part_b_concrete_builder2(Product *product)
{
add_part(product, "部件Y");
}
// 获取结果的通用实现,确保安全返回产品实例
Product *get_result_common(void *builder_void_ptr)
{
ConcreteBuilder *builder = (ConcreteBuilder *)builder_void_ptr;
return &builder->product;
}
// 导演类构建方法
void construct(Director *director, Builder *builder, void *builder_void_ptr, Product **result)
{
builder->build_part_a((Product *)builder_void_ptr);
builder->build_part_b((Product *)builder_void_ptr);
*result = builder->get_result(builder_void_ptr);
}
int main()
{
// 初始化Director
Director director = {.construct = construct};
// 初始化ConcreteBuilder实例
ConcreteBuilder builder1;
init_product(&builder1.product);
Builder b1 = {
.build_part_a = build_part_a_concrete_builder1,
.build_part_b = build_part_b_concrete_builder1,
.get_result = get_result_common};
ConcreteBuilder builder2;
init_product(&builder2.product);
Builder b2 = {
.build_part_a = build_part_a_concrete_builder2,
.build_part_b = build_part_b_concrete_builder2,
.get_result = get_result_common};
Product *p1 = NULL;
Product *p2 = NULL;
printf("使用ConcreteBuilder1的方法建造产品: \n");
director.construct(&director, &b1, &builder1, &p1);
show_product(p1);
puts("");
printf("使用ConcreteBuilder2的方法建造产品: \n");
director.construct(&director, &b2, &builder2, &p2);
show_product(p2);
puts("");
free_product(p1);
free_product(p2);
return 0;
}
总结
- 创建者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式时适用的模式;
- 使得建造代码与表示代码分离,隐藏了该产品是如何组装的,多疑若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了