digitalmars.D.announce - Builder: Tiny Utility Library to Add a Builder API to Classes
- Vijay Nayar (44/44) Jan 05 https://code.dlang.org/packages/builder
- Vladimir Marchevsky (4/11) Jan 05 Hopefully we'll finally have named arguments. Considering they
- Vijay Nayar (8/22) Jan 06 Named arguments would definitely obviate this tool, but in the
- thebluepandabear (2/5) Jan 06 Good 👍
- Vijay Nayar (27/32) Jan 06 The builder methods are automatically generated and go up the
- thebluepandabear (4/39) Jan 06 I meant what if I want some extra behavior for the setter method
https://code.dlang.org/packages/builder Interacting with many projects that are related to Java, I could not help notice that a common "Builder API" is not easily available in D. What is the problem? When constructing classes, especially those with lots of data, there are two broad ways of building the object. 1. Initializing each field in a different statement. ``` A a = new A(); a.setName("Bob"); a.setAge(20); a.isProbation(false); a.isActive(true); ... ``` This approach involves writing a lot of boiler plate, and it doesn't work well for quickly creating objects inline, such as during a function call. 2. Using a constructor with many arguments. ``` A a = new A("Bob", 20, false, true); ``` This approach can construct arguments inline, such as during a function call, however, the arguments are not labeled, making it easy to get the order wrong or for the meaning to be unclear. This library allows one to get the best of both worlds. Construction within a single statement, but also without losing meaning of the parameters, e.g. ``` class A { string name; int age; bool isProbation; bool isActive; mixin AddBuilder!(typeof(this)); } A a = A.builder() .name("Bob") .age(20) .isProbation(false) .isActive(true) .build(); ```
Jan 05
On Thursday, 5 January 2023 at 21:48:40 UTC, Vijay Nayar wrote:2. Using a constructor with many arguments. ``` A a = new A("Bob", 20, false, true); ``` This approach can construct arguments inline, such as during a function call, however, the arguments are not labeled, making it easy to get the order wrong or for the meaning to be unclear.Hopefully we'll finally have named arguments. Considering they were accepted to language more than two years ago - maybe in the next century...
Jan 05
On Thursday, 5 January 2023 at 23:31:36 UTC, Vladimir Marchevsky wrote:On Thursday, 5 January 2023 at 21:48:40 UTC, Vijay Nayar wrote:Named arguments would definitely obviate this tool, but in the meanwhile, this tool basically lets you achieve the same objectives in terms of single-expression construction and clearly labeled arguments. I guess one extra advantage of the `builder` library is that you also don't have to bother writing a constructor at all and can just use the default one.2. Using a constructor with many arguments. ``` A a = new A("Bob", 20, false, true); ``` This approach can construct arguments inline, such as during a function call, however, the arguments are not labeled, making it easy to get the order wrong or for the meaning to be unclear.Hopefully we'll finally have named arguments. Considering they were accepted to language more than two years ago - maybe in the next century...
Jan 06
.isActive(true) .build(); ```Good 👍 how would I extend the builder methods?
Jan 06
On Friday, 6 January 2023 at 09:26:51 UTC, thebluepandabear wrote:The builder methods are automatically generated and go up the inheritance chain to capture all the fields in your class. (I assume that you are referring to inheritance when you say "extend"?) Here is one of the unit-tests demonstrating this: ``` class A2 { int a; string b; } class B2 : A2 { int c; mixin AddBuilder!(typeof(this)); } /// All inherited fields should be available from the builder. unittest { B2 b2 = B2.builder() .a(3) .b("ham") .c(4) .build(); assert(b2.a == 3); assert(b2.b == "ham"); assert(b2.c == 4); } ```.isActive(true) .build(); ```Good 👍 how would I extend the builder methods?
Jan 06
On Friday, 6 January 2023 at 12:54:07 UTC, Vijay Nayar wrote:On Friday, 6 January 2023 at 09:26:51 UTC, thebluepandabear wrote:I meant what if I want some extra behavior for the setter method other than just assigning a value to the field. E.g. if I set a password field, I might want to validate that it's valid.The builder methods are automatically generated and go up the inheritance chain to capture all the fields in your class. (I assume that you are referring to inheritance when you say "extend"?) Here is one of the unit-tests demonstrating this: ``` class A2 { int a; string b; } class B2 : A2 { int c; mixin AddBuilder!(typeof(this)); } /// All inherited fields should be available from the builder. unittest { B2 b2 = B2.builder() .a(3) .b("ham") .c(4) .build(); assert(b2.a == 3); assert(b2.b == "ham"); assert(b2.c == 4); } ```.isActive(true) .build(); ```Good 👍 how would I extend the builder methods?
Jan 06