构造器模式-现代C++设计模式

简单构造器

适用类型

通过设置构造器函数,对复杂的类进行构造,流式构造器可以更加方便实现构造。
注意:构造器模式需要连贯地进行对象构造,不能间断

实现代码

#include<iostream>
#include <memory>
#include<vector>
using namespace std;

//被构造的对象
struct HtmlElement{
	string name, text;
	vector <HtmlElement> elements;
	HtmlElement() {}
	HtmlElement(const string& name, const string& text)
		: name(name), text(text) {}
	string str(int indent = 0) const {
		string temp=name+text;
		for (auto i : elements) {
			temp += i.name;
			temp += i.text;
		}
		return temp;
	}
};
//对象构造器
struct HtmlBuilder {
	HtmlElement root;
	HtmlBuilder(string root_name) {
		root.name = root_name;
	}

	//流式构造器,可以连续进行构造
	HtmlBuilder& add_child(string child_name, string child_text) {
		root.elements.emplace_back(child_name, child_text);
		return *this;
	}
	string str() { return root.str(); }
};

int main() {
	
	HtmlBuilder builder{ "begin\n" };//声明构造器
	builder.add_child("1", "a").add_child("2", "b"); //进行流式构造
	cout << builder.str();
	return 0;
}

组合构造器

适用类型

使用多个构造器来构建单个对象

类图

在这里插入图片描述

将代码的结构分为多个独立基类,是为了避免对象实例赘余

实现代码

#include<iostream>
#include <memory>
using namespace std;
//声明各个类
class PersonBuilderBase; 
class PersonBuilder;
class PersonJobBuilder;
class PersonBuilder;

//数据成员类、包含了两类信息
class Person {
	Person() {}
	string street_address, city;

	string company_name, position;
	int annual_income = 0;
public:
	string get() { return company_name; }
	static PersonBuilder& create();

	friend class PersonBuilder;	//将构造器声明为友元类
	friend class PersonAddressBuilder;
	friend class PersonJobBuilder;
};

class PersonBuilderBase {
protected:
	Person & person; //存储引用是为了减少对象的生成
	explicit PersonBuilderBase(Person& person) :person{ person } {}
	//explicit 控制构造函数的调用,避免了隐式类型转换
public:
	operator Person() { //使用默认移动构造函数
		return move(person);
	}
	PersonAddressBuilder lives()const; //两个返回构造器的函数
	PersonJobBuilder works()const;
};



//实际构建对象的类
class PersonBuilder :public PersonBuilderBase {
	Person p;
public:
	PersonBuilder() :PersonBuilderBase{ p } {}
};

//用来设置地址部分的类
class PersonAddressBuilder : public PersonBuilderBase {
public:
	explicit PersonAddressBuilder(Person& person) :PersonBuilderBase{ person } {}
	PersonAddressBuilder& at(string street_address) {
		person.street_address = street_address;
		return *this;
	}

};

//用来设置职业部分的类
class PersonJobBuilder : public PersonBuilderBase {
public:
	explicit PersonJobBuilder(Person& person) :PersonBuilderBase{ person } {}
	PersonJobBuilder& at(string company_name) {
		person.company_name = company_name;
		return *this;
	}

};

//全局变量,作为构造器
PersonBuilder temp;

//获取构造器
PersonBuilder& Person::create() {
	return temp;
}

//设置构造器,以Base内的引用作为参数
PersonAddressBuilder PersonBuilderBase::lives()const {
	PersonAddressBuilder  temp(person);
	return temp;
}

PersonJobBuilder PersonBuilderBase::works()const {
	PersonJobBuilder  temp(person);
	return temp;
}

int main() {
	Person p = Person::create().lives().at("london").works().at("HUST");
	cout << p.get();
	return 1;
}

特点

通常能够流式构建,构造器的函数需要返回this指针
为了强制用户使用构造器,将目标对象的构造函数限制不可用,通过静态函数得到构造器

总结

通过上述代码,我们可以观察到,构造器模式能够简化对象或一系列对象的构造过程,分为多个步骤进行对象构造,适合复杂对象的构建。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值