参考:
C++ 中简化set/get 函数封装的 方式_c++ get set-CSDN博客
定义一个模板类
你可以创建一个模板类Property
,用于封装设置和获取功能:
template<typename T>
class Property {
private:T value;public:void set(const T& v) {value = v;}T get() const {return value;}
};
使用模板类
在你的原始类中,你可以用Property
类替代所有的成员变量和它们的setter/getter方法:
class SoftwareUpdate {
public:Property<std::string> version;Property<std::string> updateUrl;Property<std::vector<std::string>> updateFiles;Property<std::string> updateDir;Property<std::string> updateScript;Property<std::string> updateScriptArgs;Property<std::string> updateScriptOutput;Property<std::string> updateScriptError;// 其他方法和成员...
};
如何使用
使用新的模板化属性是直接的:
SoftwareUpdate su;
su.version.set("1.0");
std::string ver = su.version.get();su.updateFiles.set({"file1.txt", "file2.txt"});
auto files = su.updateFiles.get();// 等等...
优势
这种方法的优势在于:
减少冗余代码:你不再需要为每个属性编写独立的setter和getter方法。
提高可维护性:任何对属性访问逻辑的修改都可以在Property模板类中一次性完成,而不需要修改多个地方。
类型安全:模板确保了类型安全,防止了某些类型错误。
这种方法适用于需要大量简单访问方法的类。如果你的属性访问逻辑更复杂(比如需要验证或其他逻辑处理),那么可能需要更定制的解决方案。
这种方法属于“封装属性(Property Capsule)”模式,有时也被称作“封装字段(Encapsulated Field)”模式。这种模式主要目的是将数据访问封装在单独的类或结构中,以便统一管理数据访问逻辑,减少代码重复,并提高数据操作的安全性和灵活性。
模式特点
封装性:通过封装字段和访问逻辑,增强了类的内聚性和封装性。
可维护性:当需要改变数据访问逻辑或添加额外的逻辑(如验证或通知)时,只需要修改封装类,而不需要修改每个使用点。
灵活性:可以轻松地对属性的读写操作进行扩展,比如添加日志记录、错误处理或者触发事件等。
与设计模式的关系
尽管“封装属性”模式不是传统设计模式中经常提到的模式之一,它却与几个经典设计模式有相似之处:
桥接模式(Bridge):通过将实现从抽象中分离出来,可以改变实现而不影响客户代码。
代理模式(Proxy):Property类在某种意义上充当原始数据的代理,提供额外的封装和控制。
策略模式(Strategy):可以将不同的访问策略封装为策略对象,通过Property类使用不同策略来控制数据访问。
这种模式非常适用于构建高度模块化和易于维护的系统,特别是在属性多、访问频繁且可能未来需要扩展的场景中。