Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

effective java builder idiom equivalent in c++?

This is a great idiom I've been using since reading Effective Java. I've been trying to find a C++ equivalent or something similar and have had little luck. The traditional builder pattern found in the GoF book isn't really applicable in my case. It's one complicated object that has a very messy constructor. Below is a small implementation of the 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();

    }
}
like image 735
Mike Lyons Avatar asked Dec 17 '22 09:12

Mike Lyons


2 Answers

Not only can it be adapted to C++ but rather the idiom has been adapted from C++.

I think the first time I heard of this idiom was before Java came into existence. IIRC Bjarne Stroustrup mentions this in C++ 2nd Edition as an explanation of why C++ does not need Smalltalk style named parameters.

I could have my dates wrong but this is about 15 years old in C++.

EDIT: It seems it wad first described in Design and Evolution of C++ (6.5.1) where it was called named function parameters

like image 147
Miserable Variable Avatar answered Dec 31 '22 01:12

Miserable Variable


#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));

}

I made minimal changes to make it C++, fast, and safe. http://ideone.com/sCH1V

like image 38
Mooing Duck Avatar answered Dec 31 '22 02:12

Mooing Duck