文章目录
- 一、前言
- 二、为什么需要`Builder Pattern`,`Builder Pattern`到底解决了什么实际问题?为什么不用set()方法?
- 2.1 初学者有那些对象的属性初始化方法呢?
- 2.1.1 构造函数的弊端
- 2.1.1.1 对于属性的初始化只能是固定的顺序
- 2.1.2 用set()函数初始化类的弊端
- 2.1.2.1 类属性太多,类的可读性太差
- 三、`Builder Pattern`各种写法的对比
- 3.1 《C++20设计模式》中的流式构造器
- 3.1.1 流式构造器
- 3.1.1.1 UML类图
- 3.1.1.2 实现
- 3.2 传统构造器
- 3.2.1 UML类图
- 3.2.2实现
- 3.3 组合构造器
- 3.3.1UML类图
- 3.3.2实现
- 四、总结
一、前言
笔者时刚学习Builder Pattern
,遇到了很多问题,在此汇总一下,也希望能帮到你,如有错误请指正。
- 为什么需要
Builder Pattern
,Builder Pattern
到底解决了什么实际问题?为什么不用set()方法? - 《C++20:设计模式》流式构造器到底怎么实现的?
friend
关键字的使用是否必要? - 常规的构造器怎么实现?他能解决的问题?
- 组合构造器的实现?
相关代码可以在这里,如有帮助给个star!AidenYuanDev/design_patterns_in_modern_Cpp_20
二、为什么需要Builder Pattern
,Builder Pattern
到底解决了什么实际问题?为什么不用set()方法?
首先明确一个点,Builder Pattern
主要是对于对象的属性初始化的研究,也就是我们怎么样的方式创建对象才能高内聚,低耦合,实现更优雅。
2.1 初学者有那些对象的属性初始化方法呢?
- 使用构造函数 —— 属性的初始化只能是固定的顺序
- 创建set()函数初始化函数 —— 类属性太多,类的可读性太差
2.1.1 构造函数的弊端
2.1.1.1 对于属性的初始化只能是固定的顺序
重载的特性:如果一个构造函数的参数个数,参数类型,参数顺序一致的话就说他是同一个构造函数
举个例子:
class monster {
public:// 这两个构造函数是不能同时出现的,编译器会认为他们是同一个函数。monster(string name, int attack_damage, int defense) {_name = name;_attack_damage = attack_damage;_defense = defense;}/*monster(string name, int defense, int attack_damage) {_name = name;_attack_damage = attack_damage;_defense = defense;}
*/private:string _name;int _attack_damage; // 攻击力int _defense; // 防御力
};
所以说要想按任意顺序初始化类的属性,该怎么办呢?没错可以用set()方法
2.1.2 用set()函数初始化类的弊端
2.1.2.1 类属性太多,类的可读性太差
注:这里用了流式(也就是返回类自己的指针,主要简化main中初始化过程)
举个例子:
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <list>class Vehicle {
private:// 基本属性std::string make;std::string model;int year;double price;// 动力属性double engineSize;int horsepower;std::string fuelType;// 尺寸和重量double length;double width;double height;double curbWeight;// 车辆特征std::vector<std::string> features;std::map<std::string, std::string> specifications;std::set<std::string> safetyFeatures;// 拥有者信息std::list<std::string> previousOwners;std::map<std::string, std::string> ownerDetails;public:// 构造函数Vehicle(std::string make, std::string model, int year, double price): make(make), model(model), year(year), price(price) {}// 流式设置方法Vehicle& setMake(const std::string &make) { this->make = make; return *this; }Vehicle& setModel(const std::string &model) { this->model = model; return *this; }Vehicle& setYear(int year) { this->year = year; return *this; }Vehicle& setPrice(double price) { this->price = price; return *this; }Vehicle& setEngineSize(double engineSize) { this->engineSize = engineSize; return *this; }Vehicle& setHorsepower(int horsepower) { this->horsepower = horsepower; return *this; }Vehicle& setFuelType(const std::string &fuelType) { this->fuelType = fuelType; return *this; }Vehicle& setLength(double length) { this->length = length; return *this; }Vehicle& setWidth(double width) { this->width = width; return *this; }Vehicle& setHeight(double height) { this->height = height; return *this; }Vehicle& setCurbWeight(double curbWeight) { this->curbWeight = curbWeight; return *this; }Vehicle& addFeature(const std::string &feature) { features.push_back(feature); return *this; }Vehicle& addSpecification(const std::string &key, const std::string &value) { specifications[key] = value; return *this; }Vehicle& addSafetyFeature(const std::string &feature) { safetyFeatures.insert(feature); return *this; }Vehicle& addPreviousOwner(const std::string &owner) { previousOwners.push_back(owner); return *this; }Vehicle& addOwnerDetail(const std::string &key, const std::string &value) { ownerDetails[key] = value; return *this; }// 获取属性的方法std::string getMake() const { return make; }std::string getModel() const { return model; }int getYear() const { return year; }double getPrice() const { return price; }double getEngineSize() const { return engineSize; }int getHorsepower() const { return horsepower; }std::string getFuelType() const { return fuelType; }double getLength() const { return length; }double getWidth() const { return width; }double getHeight() const { return height; }double getCurbWeight() const { return curbWeight; }std::vector<std::string> getFeatures() const { return features; }std::map<std::string, std::string> getSpecifications() const { return specifications; }std::set<std::string> getSafetyFeatures() const { return safetyFeatures; }std::list<std::string> getPreviousOwners() const { return previousOwners; }std::map<std::string, std::string> getOwnerDetails() const { return ownerDetails; }// 打印车辆信息的方法void printVehicleInfo() const {std::cout << "Make: " << make << "\nModel: " << model << "\nYear: " << year << "\nPrice: $" << price << "\n";std::cout << "Engine Size: " << engineSize << "L\nHorsepower: " << horsepower << "\nFuel Type: " << fuelType << "\n";std::cout << "Dimensions (LxWxH): " << length << " x " << width << " x " << height << " meters\n";std::cout << "Curb Weight: " << curbWeight << " kg\n";std::cout << "Features:\n";for (const auto &feature : features) {std::cout << "- " << feature << "\n";}std::cout << "Specifications:\n";for (const auto &spec : specifications) {std::cout << spec.first << ": " << spec.second << "\n";}std::cout << "Safety Features:\n";for (const auto &safety : safetyFeatures) {std::cout << "- " << safety << "\n";}std::cout << "Previous Owners:\n";for (const auto &owner : previousOwners) {std::cout << "- " << owner << "\n";}std::cout << "Owner Details:\n";for (const auto &detail : ownerDetails) {std::cout << detail.first << ": " << detail.second << "\n";}}
};int main() {Vehicle car("Toyota", "Camry", 2021, 24000);car.setEngineSize(2.5).setHorsepower(203).setFuelType("Gasoline").setLength(4.88).setWidth(1.84).setHeight(1.45).setCurbWeight(1495).addFeature("Air Conditioning").addFeature("Navigation System").addSpecification("Transmission", "8-speed automatic").addSpecification("Drivetrain", "FWD").addSafetyFeature("ABS").addSafetyFeature("Airbags").addPreviousOwner("John Doe").addOwnerDetail("Current Owner", "Jane Smith");car.printVehicleInfo();return 0;
}
三、Builder Pattern
各种写法的对比
3.1 《C++20设计模式》中的流式构造器
流式构造器要明白他的意思要把它分成两部分:
- 构造器:就是把set方法从原有的类中拿出来,建立一个新类,用这个新类构造原来的类,实现解耦。
- 流式:
set()
返回值不再是void
,现在返回类的指针
3.1.1 流式构造器
- 流式构造器重载
Vehicle()
,就可以省去返回build()
步骤 - 这里注意要把流式构造器设置为(友元),不然访问不了被造的类的私有成员函数。
是否应该使用friend关键字,后面讨论(friend破坏类的封装,到底要不要用,应不应该用?)
3.1.1.1 UML类图
3.1.1.2 实现
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <list>
#include <memory>class Vehicle {
private:// 基本属性std::string make;std::string model;int year;double price;// 动力属性double engineSize;int horsepower;std::string fuelType;// 尺寸和重量double length;double width;double height;double curbWeight;// 车辆特征std::vector<std::string> features;std::map<std::string, std::string> specifications;std::set<std::string> safetyFeatures;// 拥有者信息std::list<std::string> previousOwners;std::map<std::string, std::string> ownerDetails;public:// 构造函数Vehicle(const std::string& make, const std::string& model, int year, double price): make(make), model(model), year(year), price(price), engineSize(0), horsepower(0), length(0), width(0), height(0), curbWeight(0) {}// 打印车辆信息的方法void printVehicleInfo() const {std::cout << "Make: " << make << "\nModel: " << model << "\nYear: " << year << "\nPrice: $" << price << "\n";std::cout << "Engine Size: " << engineSize << "L\nHorsepower: " << horsepower << "\nFuel Type: " << fuelType << "\n";std::cout << "Dimensions (LxWxH): " << length << " x " << width << " x " << height << " meters\n";std::cout << "Curb Weight: " << curbWeight << " kg\n";std::cout << "Features:\n";for (const auto &feature : features) {std::cout << "- " << feature << "\n";}std::cout << "Specifications:\n";for (const auto &spec : specifications) {std::cout << spec.first << ": " << spec.second << "\n";}std::cout << "Safety Features:\n";for (const auto &safety : safetyFeatures) {std::cout << "- " << safety << "\n";}std::cout << "Previous Owners:\n";for (const auto &owner : previousOwners) {std::cout << "- " << owner << "\n";}std::cout << "Owner Details:\n";for (const auto &detail : ownerDetails) {std::cout << detail.first << ": " << detail.second << "\n";}}// 友元声明,允许构建器访问私有成员friend class VehicleBuilder;
};class VehicleBuilder {
private:std::unique_ptr<Vehicle> vehicle;public:// 构造函数VehicleBuilder(const std::string& make, const std::string& model, int year, double price): vehicle(std::make_unique<Vehicle>(make, model, year, price)) {}// 流式设置方法VehicleBuilder& setEngineSize(double engineSize) { vehicle->engineSize = engineSize; return *this; }VehicleBuilder& setHorsepower(int horsepower) { vehicle->horsepower = horsepower; return *this; }VehicleBuilder& setFuelType(const std::string &fuelType) { vehicle->fuelType = fuelType; return *this; }VehicleBuilder& setLength(double length) { vehicle->length = length; return *this; }VehicleBuilder& setWidth(double width) { vehicle->width = width; return *this; }VehicleBuilder& setHeight(double height) { vehicle->height = height; return *this; }VehicleBuilder& setCurbWeight(double curbWeight) { vehicle->curbWeight = curbWeight; return *this; }VehicleBuilder& addFeature(const std::string &feature) { vehicle->features.push_back(feature); return *this; }VehicleBuilder& addSpecification(const std::string &key, const std::string &value) { vehicle->specifications[key] = value; return *this; }VehicleBuilder& addSafetyFeature(const std::string &feature) { vehicle->safetyFeatures.insert(feature); return *this; }VehicleBuilder& addPreviousOwner(const std::string &owner) { vehicle->previousOwners.push_back(owner); return *this; }VehicleBuilder& addOwnerDetail(const std::string &key, const std::string &value) { vehicle->ownerDetails[key] = value; return *this; }// 类型转换运算符重载operator std::unique_ptr<Vehicle>() { return std::move(vehicle); }
};int main() {std::unique_ptr<Vehicle> car = VehicleBuilder("Toyota", "Camry", 2021, 24000).setEngineSize(2.5).setHorsepower(203).setFuelType("Gasoline").setLength(4.88).setWidth(1.84).setHeight(1.45).setCurbWeight(1495).addFeature("Air Conditioning").addFeature("Navigation System").addSpecification("Transmission", "8-speed automatic").addSpecification("Drivetrain", "FWD").addSafetyFeature("ABS").addSafetyFeature("Airbags").addPreviousOwner("John Doe").addOwnerDetail("Current Owner", "Jane Smith");car->printVehicleInfo();return 0;
}
3.2 传统构造器
传统构造器是怎么实现的?他的优点是什么?
虽然说上一个流式构造器,已经非常优秀了,但是经典构造器依旧有优点(这点见仁见智)!
方式:要创建新的对象,就写一个具体的类实现抽象类。
优点 :
- 创建一个具体的类,后下次就不用创建了,直接用就可以,提高复用性 。
- 我们可以选择不同的类,实现选配的效果
3.2.1 UML类图
3.2.2实现
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <list>
#include <memory>// 产品类
class Vehicle {
private:// 基本属性std::string make;std::string model;int year;double price;// 动力属性double engineSize;int horsepower;std::string fuelType;// 尺寸和重量double length;double width;double height;double curbWeight;// 车辆特征std::vector<std::string> features;std::map<std::string, std::string> specifications;std::set<std::string> safetyFeatures;// 拥有者信息std::list<std::string> previousOwners;std::map<std::string, std::string> ownerDetails;public:// 设置各属性的方法void setMake(const std::string& make) { this->make = make; }void setModel(const std::string& model) { this->model = model; }void setYear(int year) { this->year = year; }void setPrice(double price) { this->price = price; }void setEngineSize(double engineSize) { this->engineSize = engineSize; }void setHorsepower(int horsepower) { this->horsepower = horsepower; }void setFuelType(const std::string& fuelType) { this->fuelType = fuelType; }void setLength(double length) { this->length = length; }void setWidth(double width) { this->width = width; }void setHeight(double height) { this->height = height; }void setCurbWeight(double curbWeight) { this->curbWeight = curbWeight; }void addFeature(const std::string& feature) { features.push_back(feature); }void addSpecification(const std::string& key, const std::string& value) { specifications[key] = value; }void addSafetyFeature(const std::string& feature) { safetyFeatures.insert(feature); }void addPreviousOwner(const std::string& owner) { previousOwners.push_back(owner); }void addOwnerDetail(const std::string& key, const std::string& value) { ownerDetails[key] = value; }// 打印车辆信息的方法void printVehicleInfo() const {std::cout << "Make: " << make << "\nModel: " << model << "\nYear: " << year << "\nPrice: $" << price << "\n";std::cout << "Engine Size: " << engineSize << "L\nHorsepower: " << horsepower << "\nFuel Type: " << fuelType << "\n";std::cout << "Dimensions (LxWxH): " << length << " x " << width << " x " << height << " meters\n";std::cout << "Curb Weight: " << curbWeight << " kg\n";std::cout << "Features:\n";for (const auto &feature : features) {std::cout << "- " << feature << "\n";}std::cout << "Specifications:\n";for (const auto &spec : specifications) {std::cout << spec.first << ": " << spec.second << "\n";}std::cout << "Safety Features:\n";for (const auto &safety : safetyFeatures) {std::cout << "- " << safety << "\n";}std::cout << "Previous Owners:\n";for (const auto &owner : previousOwners) {std::cout << "- " << owner << "\n";}std::cout << "Owner Details:\n";for (const auto &detail : ownerDetails) {std::cout << detail.first << ": " << detail.second << "\n";}}
};// 抽象建造者
class VehicleBuilder {
public:virtual ~VehicleBuilder() = default;virtual void setMake() = 0;virtual void setModel() = 0;virtual void setYear() = 0;virtual void setPrice() = 0;virtual void setEngineSize() = 0;virtual void setHorsepower() = 0;virtual void setFuelType() = 0;virtual void setDimensions() = 0;virtual void setCurbWeight() = 0;virtual void addFeatures() = 0;virtual void addSpecifications() = 0;virtual void addSafetyFeatures() = 0;virtual void addPreviousOwners() = 0;virtual void addOwnerDetails() = 0;virtual std::unique_ptr<Vehicle> getVehicle() = 0;
};// 具体建造者
class ConcreteVehicleBuilder : public VehicleBuilder {
private:std::unique_ptr<Vehicle> vehicle;public:ConcreteVehicleBuilder() {vehicle = std::make_unique<Vehicle>();}void setMake() override {vehicle->setMake("Toyota");}void setModel() override {vehicle->setModel("Camry");}void setYear() override {vehicle->setYear(2021);}void setPrice() override {vehicle->setPrice(24000);}void setEngineSize() override {vehicle->setEngineSize(2.5);}void setHorsepower() override {vehicle->setHorsepower(203);}void setFuelType() override {vehicle->setFuelType("Gasoline");}void setDimensions() override {vehicle->setLength(4.88);vehicle->setWidth(1.84);vehicle->setHeight(1.45);}void setCurbWeight() override {vehicle->setCurbWeight(1495);}void addFeatures() override {vehicle->addFeature("Air Conditioning");vehicle->addFeature("Navigation System");}void addSpecifications() override {vehicle->addSpecification("Transmission", "8-speed automatic");vehicle->addSpecification("Drivetrain", "FWD");}void addSafetyFeatures() override {vehicle->addSafetyFeature("ABS");vehicle->addSafetyFeature("Airbags");}void addPreviousOwners() override {vehicle->addPreviousOwner("John Doe");}void addOwnerDetails() override {vehicle->addOwnerDetail("Current Owner", "Jane Smith");}std::unique_ptr<Vehicle> getVehicle() override {return std::move(vehicle);}
};// 指挥者类
class Director {
private:VehicleBuilder* builder;public:void setBuilder(VehicleBuilder* builder) {this->builder = builder;}std::unique_ptr<Vehicle> construct() {builder->setMake();builder->setModel();builder->setYear();builder->setPrice();builder->setEngineSize();builder->setHorsepower();builder->setFuelType();builder->setDimensions();builder->setCurbWeight();builder->addFeatures();builder->addSpecifications();builder->addSafetyFeatures();builder->addPreviousOwners();builder->addOwnerDetails();return builder->getVehicle();}
};// 主函数
int main() {Director director;ConcreteVehicleBuilder builder;director.setBuilder(&builder);std::unique_ptr<Vehicle> car = director.construct();car->printVehicleInfo();return 0;
}
3.3 组合构造器
个人觉得这个依然是巅峰了,当时第一次看到这个实现方式真的是惊为天人!
优点:可以选配(特定一类属性进行初始化,再也不用担心到不到要初始化的类了!)
3.3.1UML类图
3.3.2实现
#include <algorithm>
#include <iostream>
#include <list>
#include <vector>
#include <map>
#include <set>
#include <memory>
using namespace std;class Vehicle_Builder;
class V_Basic_Properties_Builder;
class V_Dynamic_Properties_Builder;
class V_Size_And_Weight_Builder;
class V_Vehicle_Features_Builder;
class V_Owner_Information_Builder;class Vehicle {
private:// 基本属性std::string make;std::string model;int year;double price;// 动力属性double engineSize;int horsepower;std::string fuelType;// 尺寸和重量double length;double width;double height;double curbWeight;// 车辆特征std::vector<std::string> features;std::map<std::string, std::string> specifications;std::set<std::string> safetyFeatures;// 拥有者信息std::list<std::string> previousOwners;std::map<std::string, std::string> ownerDetails;public:static Vehicle_Builder create();Vehicle(){}// 打印车辆信息的方法void printVehicleInfo() const {std::cout << "制造商: " << make << "\n型号: " << model << "\n年份: " << year << "\n价格: $" << price << "\n";std::cout << "发动机大小: " << engineSize << "L\n马力: " << horsepower << "\n燃料类型: " << fuelType << "\n";std::cout << "尺寸 (长x宽x高): " << length << " x " << width << " x " << height << " 米\n";std::cout << "整备质量: " << curbWeight << " 千克\n";std::cout << "特征:\n";for (const auto &feature : features) {std::cout << "- " << feature << "\n";}std::cout << "规格:\n";for (const auto &spec : specifications) {std::cout << spec.first << ": " << spec.second << "\n";}std::cout << "安全特征:\n";for (const auto &safety : safetyFeatures) {std::cout << "- " << safety << "\n";}std::cout << "之前的车主:\n";for (const auto &owner : previousOwners) {std::cout << "- " << owner << "\n";}std::cout << "车主详细信息:\n";for (const auto &detail : ownerDetails) {std::cout << detail.first << ": " << detail.second << "\n";}}// 友元声明,允许构建器访问私有成员friend class Vehicle_Builder;friend class V_Basic_Properties_Builder;friend class V_Dynamic_Properties_Builder;friend class V_Size_And_Weight_Builder;friend class V_Vehicle_Features_Builder;friend class V_Owner_Information_Builder;
};class Vehicle_Builder_Base {
protected:Vehicle& vehicle;explicit Vehicle_Builder_Base(Vehicle& vehicle) : vehicle(vehicle) {}public:operator Vehicle() { return std::move(vehicle); }V_Basic_Properties_Builder basic_properties() const;V_Dynamic_Properties_Builder dynamic_properties() const;V_Size_And_Weight_Builder size_and_weight() const;V_Vehicle_Features_Builder vehicle_features() const;V_Owner_Information_Builder owner_information() const;
};class Vehicle_Builder : public Vehicle_Builder_Base {
protected:Vehicle vehicle;
public:Vehicle_Builder() : Vehicle_Builder_Base(vehicle) {}
};class V_Basic_Properties_Builder : public Vehicle_Builder_Base {
public:explicit V_Basic_Properties_Builder(Vehicle& vehicle) : Vehicle_Builder_Base(vehicle) {}V_Basic_Properties_Builder& make(const std::string& make) {vehicle.make = make;return *this;}V_Basic_Properties_Builder& model(const std::string& model) {vehicle.model = model;return *this;}V_Basic_Properties_Builder& year(int year) {vehicle.year = year;return *this;}V_Basic_Properties_Builder& price(double price) {vehicle.price = price;return *this;}
};class V_Dynamic_Properties_Builder : public Vehicle_Builder_Base {
public:explicit V_Dynamic_Properties_Builder(Vehicle& vehicle) : Vehicle_Builder_Base(vehicle) {}V_Dynamic_Properties_Builder& engineSize(double engineSize) {vehicle.engineSize = engineSize;return *this;}V_Dynamic_Properties_Builder& horsepower(int horsepower) {vehicle.horsepower = horsepower;return *this;}V_Dynamic_Properties_Builder& fuelType(const std::string& fuelType) {vehicle.fuelType = fuelType;return *this;}
};class V_Size_And_Weight_Builder : public Vehicle_Builder_Base {
public:explicit V_Size_And_Weight_Builder(Vehicle& vehicle) : Vehicle_Builder_Base(vehicle) {}V_Size_And_Weight_Builder& length(double length) {vehicle.length = length;return *this;}V_Size_And_Weight_Builder& width(double width) {vehicle.width = width;return *this;}V_Size_And_Weight_Builder& height(double height) {vehicle.height = height;return *this;}V_Size_And_Weight_Builder& curbWeight(double curbWeight) {vehicle.curbWeight = curbWeight;return *this;}
};class V_Vehicle_Features_Builder : public Vehicle_Builder_Base {
public:explicit V_Vehicle_Features_Builder(Vehicle& vehicle) : Vehicle_Builder_Base(vehicle) {}V_Vehicle_Features_Builder& addFeature(const std::string& feature) {vehicle.features.push_back(feature);return *this;}V_Vehicle_Features_Builder& addSpecification(const std::string& key, const std::string& value) {vehicle.specifications[key] = value;return *this;}V_Vehicle_Features_Builder& addSafetyFeature(const std::string& safetyFeature) {vehicle.safetyFeatures.insert(safetyFeature);return *this;}
};class V_Owner_Information_Builder : public Vehicle_Builder_Base {
public:explicit V_Owner_Information_Builder(Vehicle& vehicle) : Vehicle_Builder_Base(vehicle) {}V_Owner_Information_Builder& addPreviousOwner(const std::string& owner) {vehicle.previousOwners.push_back(owner);return *this;}V_Owner_Information_Builder& addOwnerDetail(const std::string& key, const std::string& value) {vehicle.ownerDetails[key] = value;return *this;}
};Vehicle_Builder Vehicle::create() {return Vehicle_Builder();
}V_Basic_Properties_Builder Vehicle_Builder_Base::basic_properties() const {return V_Basic_Properties_Builder(vehicle);
}V_Dynamic_Properties_Builder Vehicle_Builder_Base::dynamic_properties() const {return V_Dynamic_Properties_Builder(vehicle);
}V_Size_And_Weight_Builder Vehicle_Builder_Base::size_and_weight() const {return V_Size_And_Weight_Builder(vehicle);
}V_Vehicle_Features_Builder Vehicle_Builder_Base::vehicle_features() const {return V_Vehicle_Features_Builder(vehicle);
}V_Owner_Information_Builder Vehicle_Builder_Base::owner_information() const {return V_Owner_Information_Builder(vehicle);
}int main() {Vehicle vehicle = Vehicle::create().basic_properties().make("丰田").model("凯美瑞").year(2020).price(30000.0).dynamic_properties().engineSize(2.5).horsepower(203).fuelType("汽油").size_and_weight().length(4.8).width(1.8).height(1.4).curbWeight(1500).vehicle_features().addFeature("天窗").addSpecification("变速器", "自动").addSafetyFeature("ABS").owner_information().addPreviousOwner("约翰·多伊").addOwnerDetail("当前车主", "简·多伊");vehicle.printVehicleInfo();return 0;
}
四、总结
对于这三种构造器,我还是喜欢组合和流式,因为个人觉得他是真正做到把对象的创建和对象的使用分离开来的!
对于friend关键字,我平时也是可以用的,不过要更加深思熟虑,破坏封装性也是真的,但也不是不用这个C++存在的特性。
最后!作者也是刚学,写下对此设计模式的疑惑,如有错误,请指正!
点个赞吧!