Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support staged builder #159

Closed
reda-alaoui opened this issue Nov 23, 2023 · 5 comments · Fixed by #161
Closed

Support staged builder #159

reda-alaoui opened this issue Nov 23, 2023 · 5 comments · Fixed by #161
Labels
enhancement New feature or request PR welcome A PR submitted for this issue would be welcome

Comments

@reda-alaoui
Copy link

Something similar to https://immutables.github.io/immutable.html#staged-builder:

A staged builder is a compile-time safe way to ensure that all required attributes are set. The API, composed of stage interfaces, forces initialization of mandatory attributes in stages, one by one, guiding via code-completion and making it impossible to even call build() before all are set.

@Randgalt Randgalt added enhancement New feature or request PR welcome A PR submitted for this issue would be welcome labels Nov 23, 2023
@Randgalt
Copy link
Owner

@reda-alaoui do I understand correctly that this generates a small builder interface for each record component with the return value another small builder interface for the next component until all components have been set then a final build method?

@reda-alaoui
Copy link
Author

Yes

@Randgalt
Copy link
Owner

It sounds nice but, tbh, I simply don't have the time. A PR would be welcome and I can help if needed.

@siy
Copy link

siy commented Jan 1, 2024

This builder is often called "fluent builder". For most typical (for records) case when all components are required, the code which needs to be generated is simple (simpler than for regular builder) and mostly consists of interface declarations.

First version, with traditional build() as the final stage:

public interface NameAndAgeBuilder {
    static NameAndAgeBuilder builder() {
        return name -> age -> () -> new NameAndAge(name, age);
    }

    Stage1 name(String name);

    interface Stage1 {
        Stage2 age(int age);
    }

    interface Stage2 {
        NameAndAge build();
    }
}

The second version, without build() is even simpler:

public interface NameAndAgeBuilder {
    static NameAndAgeBuilder builder() {
        return name -> age -> new NameAndAge(name, age);
    }

    Stage1 name(String name);

    interface Stage1 {
        NameAndAge age(int age);
    }
}

Among other advantages, this technique enforces particular order of initialization, making code management much more convenient. For example, comparing changes in PR.

Randgalt added a commit that referenced this issue Jan 1, 2024
Closes #159

New option to have standard builder, staged builder or both
@Randgalt
Copy link
Owner

Randgalt commented Jan 1, 2024

I decided to give it a whirl. Please review: #161

Randgalt added a commit that referenced this issue Jan 1, 2024
Closes #159

New option to have standard builder, staged builder or both
Randgalt added a commit that referenced this issue Jan 1, 2024
Closes #159

New option to have standard builder, staged builder or both
Randgalt added a commit that referenced this issue Jan 1, 2024
Closes #159

New option to have standard builder, staged builder or both
Randgalt added a commit that referenced this issue Jan 1, 2024
Closes #159

New option to have standard builder, staged builder or both
Randgalt added a commit that referenced this issue Jan 4, 2024
Closes #159

New option to have standard builder, staged builder or both
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request PR welcome A PR submitted for this issue would be welcome
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants