C++实现设计模式——Builder模式
- 建造者模式定义
建造者(Builder)模式的定义:指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
举例为什么用Builder模式
- 举一个通俗的例子:
我们大家都玩游戏吧,每个角色会有很多属性,即构造参数,有一些是构造必需参数,如id,name,有一些是可以用默认的值,比如hp,level等等,游戏刚开始我们可以用默认值构造,但是当游戏过了一段时间这些属性都变得各不一样了,此时我们再次构造玩家角色的时候,只能是先构造一个初始化的,然后在后期修改赋值,如下:
Player *p1 = new Player (); p1->setName("milo"); p1->setHp(1000); p1->setleve(6); ```
但是这样有个不好的地方,那就是对象的构造过程是非连续的,也就是说对象可处于一个构造不完全的状态,我们很容易写出将对象传入各个方法,每个方法去赋值对象的某一部分这样的代码,这其实引入了一个状态空间,如果状态空间是强可控的,那还好(但依然提高了维护成本,你需要牢牢掌握住对象的构造过程,什么字段在何处被赋值);如果不可控,那么就很难保证这个对象是否被正确的构造,可能在某个方法中覆盖了某字段,也可能遗漏了某字段导致 错误。
那为了解决这个问题,建造者模式就出现了,就可以写成下面的这种方式
Player p1= PlayerBuilder.player() .name("milo") .hp(1000) .leve(6) .build();
需要构造什么参数,就加上哪个接口,其它的用默认值,这就可以绝对赋值哪个,这是第一个优点,还有一个优点,建造者模式可以随机组装构造参数的顺序,个数,这个在复杂构造的情况下很有用。
- 结构图
- 代码举例
#include <iostream> #include <string> using namespace std; class Player; class playBuilder { public: string Name; int ID; int HP; int Level; public: playBuilder() { //参数默认值 Name = "xiaoming"; ID = 1001; HP = 100; Level = 1; cout<<"默认构造函数"<<endl; } playBuilder* SetName(string Name) {this->Name = Name;return this;} playBuilder* SetID(int ID) {this->ID = ID;return this;} playBuilder* SetHP(int HP) {this->HP = HP;return this;} playBuilder* SetLevel(int Level) {this->Level = Level;return this;} Player *build(); }; class Player { public: string Name; int ID; int HP; int Level; public: string GetName() {return Name;} int GetID() {return ID;} int GetHP() {return HP;} int GetLevel() {return Level;} Player() {cout<<"默认构造函数"<<endl;} Player (playBuilder const &temp) { this->Name = temp.Name; this->ID = temp.ID; this->HP = temp.HP; this->Level = temp.Level; } ~Player() {} void show() { cout<<Name<<"-"<<ID<<"-"<<HP<<"-"<<Level<<endl; } }; Player *playBuilder::build(){ return new Player(*this); } int main() { Player * p1 = playBuilder().SetID(90)->build(); Player * p2 = playBuilder().SetID(91)->SetHP(200)->build(); Player * p3 = playBuilder().SetName("zhangsan")->SetID(92)->build(); p1->show(); p2->show(); p3->show(); return 0; }
上面这种情况就是我们要设置哪个参数就添加哪个方法set就行,对象是一个完整的创建过程,这也是我们很多地方比较常见的一种用法,它比正常的builder少了director角色,算是个简化版。
加入现在我们要求按照一定的规则进行构造,下面我们加上director,如果说builder是构造器,可以给我们随心构造的条件,那么director就好比一个指挥者,它规定着builder该怎么去创建一个目标对象。
#include <iostream> #include <string> using namespace std; class Player; class playBuilder { public: string Name; int ID; int HP; int Level; public: playBuilder() { //参数默认值 Name = "xiaoming"; ID = 1001; HP = 100; Level = 1; cout<<"默认构造函数"<<endl; } playBuilder* SetName(string Name) {this->Name = Name;return this;} playBuilder* SetID(int ID) {this->ID = ID;return this;} playBuilder* SetHP(int HP) {this->HP = HP;return this;} playBuilder* SetLevel(int Level) {this->Level = Level;return this;} Player *build(); }; class Player { public: string Name; int ID; int HP; int Level; public: string GetName() {return Name;} int GetID() {return ID;} int GetHP() {return HP;} int GetLevel() {return Level;} Player() {cout<<"默认构造函数"<<endl;} Player (playBuilder const &temp) { this->Name = temp.Name; this->ID = temp.ID; this->HP = temp.HP; this->Level = temp.Level; } ~Player() {} void show() { cout<<Name<<"-"<<ID<<"-"<<HP<<"-"<<Level<<endl; } }; Player *playBuilder::build(){ return new Player(*this); } class Director { public: playBuilder *builder; Director() { builder = new playBuilder(); } Player * construct(string Name,int ID,int HP,int Level) { //构造规则 builder = builder->SetName(Name); builder = builder->SetID(ID); builder = builder->SetHP(HP); builder = builder->SetLevel(Level); return builder->build(); } ~ Director() { delete builder; } }; int main() { Director d1; Player * p1 = d1.construct("xiaowang",999,9999,1); //输入构建规则需要的参数 Player * p2 = Director().construct("xiaosong",888,8888,8); Player * p3 = playBuilder().SetName("zhangsan")->SetID(92)->build(); p1->show(); p2->show(); p3->show(); return 0; }
如图中所示,参数的构造顺序和需要构造哪些参数都在Director中决定了,如果需要多种规则方案,就往里面添加construct方法。
以上就是builder的设计方式相关了,只是简单的介绍了为什么要用,可以怎么用,具体的线程安全等等细节,在我们实际使用的时候还是要多考虑考虑的。
标签:return,Level,int,Builder,C++,ID,Player,设计模式,HP From: https://www.cnblogs.com/jijm123/p/18366851