在生活中存在很多复杂的对象,就拿我们每天都见到的汽车举例,它由轮胎、方向盘、发动机、外壳等各种部件组成的,可谓是相当复杂。
汽车组装过程
作为一个普通消费者,我们并不关心各部件送入工厂和工厂组装的过程和细节,我们关心的只是这辆完整的汽车。用创建者模式对其进行描述:各部件和组装过程分开,一步步创建一个复杂的对象,用户只需要指定复杂对象的类型就可以得到该对象,而无需知道内部具体构造细节。
建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以 创建不同的表示。根据中文翻译的不同,也可以成为生成器模式。
抽象建造者类中定义了产品的创建方法和返回方法。
建造者模式的结构中还引入了一个指挥者类Director,该类的作用主要有两个:
指挥者针对抽象建造者编程,客户端只需要知道具体建造者的类型,即可通过指挥者类调用建造者的相关方法,返回一个完整 的产品对象。
在客户端代码中,无须关心产品对象的具体组装过程,只需确定具体建造者的类型即可,建造者模式将复杂对象的构建与对象的表现分离开来,这样使得同样的构建过程可以创建出不同的表现。
Builder图解
创建者模式包含如下角色:
优点:
缺点:
在以下情况下可以使用建造者模式:
Builder_Uml
#-*- coding: utf-8 -*-
'''
建造者模式
'''
class Product(object):
"""产品类"""
def __init__(self):
super(Product, self).__init__()
self.__description = ''
def step(self, strstep):
self.__description += "-->" + strstep
def show_description(self):
print(self.__description)
class Builder(object):
"""建造者类"""
def build_partA(self):
pass
def build_partB(self):
pass
def build_partC(self):
pass
def get_result(self):
return 0
class ConcreteBuilder1(Builder):
"""第一种建造方式"""
def __init__(self):
super(ConcreteBuilder1, self).__init__()
self.__product = Product()
def build_partA(self):
self.__product.step('first')
def build_partB(self):
self.__product.step('second')
def build_partC(self):
self.__product.step('third')
def get_result(self):
return self.__product
class ConcreteBuilder2(Builder):
"""第二种建造方式"""
def __init__(self):
super(ConcreteBuilder2, self).__init__()
self.__product = Product()
def build_partA(self):
self.__product.step('A')
def build_partB(self):
self.__product.step('B')
def build_partC(self):
self.__product.step('C')
def get_result(self):
return self.__product
class Direcotr(object):
"""指挥者类"""
def construct(self):
self.__builder.build_partA()
self.__builder.build_partB()
self.__builder.build_partC()
def set_builder(self, builder):
self.__builder = builder
if __name__ == '__main__':
director = Direcotr()
builder1 = ConcreteBuilder1()
builder2 = ConcreteBuilder2()
# 调用第一种建造方式
print('===== First way =====')
director.set_builder(builder1)
director.construct()
product1 = builder1.get_result()
product1.show_description()
# 调用第二种建造方式
print('===== Second way =====')
director.set_builder(builder2)
director.construct()
product1 = builder2.get_result()
product1.show_description()
运行结果:
===== First way =====
-->first-->second-->third
===== Second way =====
-->A-->B-->C
#ifndef PRODUCT_H
#define PRODUCT_H
#include <iostream>
#include <string>
using namespace std;
// 产品类
class Product
{
public:
Product() {
m_description = "";
}
void step(string strstep)
{
m_description += "-->" + strstep;
}
void showDescription()
{
cout << m_description << endl;
}
private:
string m_description;
};
#endif // PRODUCT_H
#ifndef BUILDER_H
#define BUILDER_H
#include "product.h"
// 建造者类
class Builder
{
public:
Builder() {}
virtual ~Builder() {}
virtual void buildPartA() {}
virtual void buildPartB() {}
virtual void buildPartC() {}
virtual Product* getResult()=0;
};
// 第一种建造方式
class ConcreteBuilder1: public Builder
{
private:
Product* m_product;
public:
ConcreteBuilder1()
{
m_product = new Product();
}
virtual ~ConcreteBuilder1(){}
virtual void buildPartA()
{
m_product->step("first");
}
virtual void buildPartB()
{
m_product->step("second");
}
virtual void buildPartC()
{
m_product->step("third");
}
virtual Product* getResult()
{
return m_product;
}
};
// 第二种建造方式
class ConcreteBuilder2: public Builder
{
private:
Product* m_product;
public:
ConcreteBuilder2()
{
m_product = new Product();
}
virtual ~ConcreteBuilder2() {}
virtual void buildPartA()
{
m_product->step("A");
}
virtual void buildPartB()
{
m_product->step("B");
}
virtual void buildPartC()
{
m_product->step("C");
}
virtual Product* getResult()
{
return m_product;
}
};
#endif // BUILDER_H
#ifndef DIRECTOR_H
#define DIRECTOR_H
#include "builder.h"
// 指挥者类
class Director
{
public:
Director() {}
void construct()
{
m_builder->buildPartA();
m_builder->buildPartB();
m_builder->buildPartC();
}
void setBuilder(Builder* builder)
{
m_builder = builder;
}
private:
Builder* m_builder;
};
#endif // DIRECTOR_H
#include <iostream>
#include "director.h"
using namespace std;
int main()
{
Director *pDirector = new Director();
Builder *pBuilder1 = new ConcreteBuilder1();
Builder *pBuilder2 = new ConcreteBuilder2();
// 调用第一种建造方式
cout << "===== First way =====" << endl;
pDirector->setBuilder(pBuilder1);
pDirector->construct();
Product *pProduct1 = pBuilder1->getResult();
pProduct1->showDescription();
cout << "===== Second way =====" << endl;
pDirector->setBuilder((pBuilder2));
pDirector->construct();
Product *pProduct2 = pBuilder2->getResult();
pProduct2->showDescription();
return 0;
}
运行结果:
===== First way =====
-->first-->second-->third
===== Second way =====
-->A-->B-->C