有效的Java构建器习语等同于c++
effective java builder idiom equivalent in c++?
这是我在阅读Effective Java后一直在使用的一个很好的成语。我一直试图找到一个c++等同或类似的东西,并没有什么运气。在GoF书中找到的传统构建器模式并不真正适用于我的情况。它是一个复杂的对象,有一个非常混乱的构造函数。下面是Java的一个小实现。
class ComplicatedObject {
private String field1;
private String field2;
private int field3;
private ComplicatedObject(Builder builder) {
this.field1 = builder.myField1;
this.field2 = builder.myField2;
this.field3 = builder.myField3;
}
public static class Builder {
private String myField1 = "some default";
private String myField2 = "some other default";
private int myField3 = -1;
public Builder() { }
public Builder field1(String val) {
this.myField1 = val;
return this;
}
public Builder field2(String val) {
this.myField2 = val;
return this;
}
public Builder field3(int val) {
this.myField3 = val;
return this;
}
public ComplicatedObject build() {
return new ComplicatedObject(this);
}
}
public static void main(final String[] args) {
//built like this
ComplicatedObject obj = new ComplicatedObject.Builder().field1("blah").field2("lol").field3(4).build();
}
}
不仅可以适应c++,而且习惯用法已经从 c++中适应了。
我想我第一次听到这个习语是在Java出现之前。IIRC Bjarne Stroustrup在c++第二版中提到了这一点,作为c++为什么不需要Smalltalk风格的命名参数的解释。
我可能记错了日期,但这是c++中大约15年前的。
编辑:它似乎是在 c++的设计和发展(6.5.1)中首次描述的,在那里它被称为命名函数参数#include <iostream>
#include <string>
using namespace std;
class ComplicatedObject {
public: class Builder {
friend class ComplicatedObject;
private: string myField1;
private: string myField2;
private: int myField3;
public: Builder()
: myField1("some default"),
myField2 ("some other default"),
myField3(-1)
{ }
public: Builder& field1(const string& val) {
myField1 = val;
return *this;
}
public: Builder& field2(const string& val) {
myField2 = val;
return *this;
}
public: Builder& field3(int val) {
myField3 = val;
return *this;
}
public: ComplicatedObject build() {
return ComplicatedObject(*this);
}
};
private: string field1;
private: string field2;
private: int field3;
private: ComplicatedObject(const Builder& builder)
:field1(builder.myField1),
field2(builder.myField2),
field3(builder.myField3)
{}
};
int main(int argc, char** argv) {
if (argc < 4) {
std::cout << "not enough params.";
return 1;
}
ComplicatedObject obj(ComplicatedObject::Builder().field1("blah").field2("lol").field3(4));
}
我做了最小的修改,使它成为c++,快速,安全。http://ideone.com/sCH1V
相关文章:
- 概念可以与 CRTP 习语一起使用吗?
- 复制和交换习语和迭代器
- 为什么当我做复制和交换习语时不调用我的复制构造函数?
- 漂亮的计数器习语的错误或格式错误的静态订单惨败?
- C++17 pimpl 习语上下文中的自定义迭代器
- 在 MyVector 中实现写入时复制习语
- 视觉 "extern __forceinline "是什么 c++ 习语?
- C 习语使用C库时,该C库期望功能指针
- 为什么 std::swap 不使用 swap 习语?
- 如何使用擦除删除习语从结构向量中删除值
- C++中的Singleton习语
- 在 C++11 中实现复制和交换习语的更好方法
- N 个并发读取器和 1 个生产者的习语或模式
- pImpl习语-将私有类实现放在cpp中有什么缺点
- 不能使用 pimpl 习语将用户定义的向量插入到封装的向量中
- Python -> C++ 习语:将 lambda 表达式存储在映射/容器中
- 安全方便的通用散列(用于 STL 无序集和映射)习语?
- 指向可配置实现的Pimpl习语
- 与构造函数参数相关的异常安全的习语
- 有效的Java构建器习语等同于c++