设计模式_07 建造者模式
7. 建造者模式
7.1 概述
将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的对象。
7.2 结构
抽象建造者(Builder):这个接口规定要实现复杂对象的那些部分的创建,并不涉及具体的对象部件的创建。
具体建造者(ConcreteBuilder):实现Builder接口,完成复杂对象的各个部分的具体创建方法。在构造过程完成后,提供产品的实例。
产品类:要创建的复杂对象。
指挥者类:调用具体建造者来创建复杂对象的各个组成部分。在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建。
7.2.1 UML结构图
7.3 实现
7.3.1 UML图
7.3.2 代码
#include<iostream>
#include<string>
using namespace std;
//CPU类
class Cpu {
public:
virtual void showCpu() {}
};
class IntelCpu : public Cpu {
public:
void showCpu() {
cout << "Intel CPU" << endl;
}
};
class AmdCpu : public Cpu {
public:
void showCpu() {
cout << "AMD CPU" << endl;
}
};
//内存类
class Memory {
public:
virtual void showMemory() {}
};
class CorsairMemory : public Memory {
public:
void showMemory() {
cout << "海盗船内存条" << endl;
}
};
class KingstonMemory : public Memory {
public:
void showMemory() {
cout << "金士顿内存条" << endl;
}
};
//主板类
class Mainboard {
public:
virtual void showMainboard () {}
};
class MsiMainboard : public Mainboard {
public:
void showMainboard() {
cout << "微星主板" << endl;
}
};
class AsusMainboard : public Mainboard {
public:
void showMainboard() {
cout << "华硕主板" << endl;
}
};
//电脑类
class Computer {
private:
Cpu* cpu;
Memory* memory;
Mainboard* mainboard;
public:
void setCpu(Cpu* cpu) {
this->cpu = cpu;
}
void setMemory(Memory* memory) {
this->memory = memory;
}
void setMainboard(Mainboard* mainboard) {
this->mainboard = mainboard;
}
void getInformation() {
this->mainboard->showMainboard();
this->cpu->showCpu();
this->memory->showMemory();
}
};
//Builder类
class ComputerBuilder {
protected:
Computer* computer = new Computer();
public:
virtual void buildCpu() {}
virtual void buildMemory() {}
virtual void buildMainboard() {}
virtual Computer* getComputer() {
return this->computer;
}
};
class MsiIntelComputerBuilder : public ComputerBuilder {
public:
void buildCpu() {
this->computer->setCpu(new IntelCpu());
}
void buildMemory() {
this->computer->setMemory(new CorsairMemory());
}
void buildMainboard() {
this->computer->setMainboard(new MsiMainboard());
}
Computer* getComputer() {
buildCpu();
buildMemory();
buildMainboard();
return this->computer;
}
};
class AsusCmdComputerBuilder : public ComputerBuilder {
public:
void buildCpu() {
this->computer->setCpu(new AmdCpu());
}
void buildMemory() {
this->computer->setMemory(new KingstonMemory());
}
void buildMainboard() {
this->computer->setMainboard(new AsusMainboard());
}
Computer* getComputer() {
buildCpu();
buildMemory();
buildMainboard();
return this->computer;
}
};
//Director类
class Director {
private:
ComputerBuilder* builder;
public:
Director(ComputerBuilder* builder) {
this->builder = builder;
}
Computer* construct() {
return builder->getComputer();
}
};
int main() {
Director* director = new Director(new MsiIntelComputerBuilder());
Computer* computer = director->construct();
computer->getInformation();
director = new Director(new AsusCmdComputerBuilder());
computer = director->construct();
computer->getInformation();
return 0;
}
7.4 优缺点
7.4.1 优点
封装性好,使用封装者模式可以有效的封装变化。在使用建造者模式的场景中一般产品类和建造者类是比较稳定的。因此,将主要的业务逻辑封装在指挥者类中对整体而言可以取得很好的稳定性。
客户端不需要知道产品内部的细节,将产品本身和产品创建过程解耦。
可以更加精细的控制产品的创建过程,将产品的创建步骤分解在不同的方法中。
很容易进行扩展,如果有新的需求,只需要创建一个新的建造者类就可以。基本不用修改之前测试过的代码。
7.4.2 缺点
建造者模式生产的产品一般具有较多的共同点,组成部分相似。如果产品差异大,则不适合用建造者模式。因此,适用范围有影响。
7.5 使用场景
创建对象较复杂,由多个部件构成,各部件种类繁多,但部件间的构造方式是稳定的。
创建复杂对象的算法独立于该对象的组成部分以及他们的装配方式,即产品的构建过程和最终表示是相互独立的。
7.6 模式扩展
当一个类构造器需要传入很多参数时,如果创建这个类的实例,可读性会很差,且容易引入错误。可以使用建造者类重构。