0

I currently have a very basic Step Builder in a C# application that is created to allow all fields as optional and it is working fine for this (although this makes it not really a Step Builder).

I know that required fields can be added to the constructor as parameters but I was wondering if there is a way to add a required field as a step so that it stays as a Step Builder by handling the required fields with interfaces instead of constructor parameters.

I have a dumb class for demonstrating

class Animal {

    private String type;
    private String name;

    public Animal(AnimalBuilder builder) {
        this.type = builder.type;
        this.name = builder.name;
    }

    public String getType() { return this.type; }
    public String getName() { return this.name; }

}

Then the Step Builder (sort of) as

class AnimalBuilder {

    private Builder builder;
    public String type;
    public String name;

    public BuilderIfc start() {
        this.builder = new Builder();
        return this.builder;
    }

    public interface withTypeIfc {
        BuilderIfc withType(String type);
    }

    public interface withNameIfc {
        BuilderIfc withName(String name);
    }

    public interface BuilderIfc {
        BuilderIfc withType(String type);
        BuilderIfc withName(String name);
        Animal build();
    }

    public class Builder : AnimalBuilder, withTypeIfc, withNameIfc, BuilderIfc {

        public BuilderIfc withType(String type) {
            this.type = type;
            return this;
        }

        public BuilderIfc withName(String name) {
            this.name = name;
            return this;
        }

        public Animal build() {
            return new Animal(this);
        }

    }

}

It works fine for these scenarios

// allow : animal has type and name
animal = new AnimalBuilder().start().withType("Dog").withName("Spanky").build();

// allow : animal has type
animal = new AnimalBuilder().start().withType("Bear").build();

But it does not work for this scenario because withType should become required instead of optional

// do not allow  : animal must have type
animal = new AnimalBuilder().start().build();
TheLovelySausage
  • 3,838
  • 15
  • 56
  • 106
  • 1
    `public BuilderIfc start() {` should return an `withTypeIfc` if you want it to be mandatory. You should stick to C# naming conventions, btw. – Fildor Mar 31 '22 at 15:24
  • @Fildor to be honest I thought I was using the C# naming conventions, can I be silly and ask which conventions are the violators? – TheLovelySausage Mar 31 '22 at 15:30
  • @Fildor also your suggestion was exactly right it sorted it nicely, can you please post it as an answer so I can accept as correct – TheLovelySausage Mar 31 '22 at 16:09
  • For conventions, have look into: https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions – Fildor Apr 01 '22 at 07:42

1 Answers1

1

If you want to enforce the setting of a specific option in your builder pattern, you can do this in different manners:

( List is probably not complete! )

  1. You can have those as a parameter to the builder-creation function.

Example for your case:

public BuilderIfc Start(string type) { /*implementation here*/ }
  1. You can enforce a "flow" by returning a specific interface.
//     vv Next in flow _must be_ ".WithType(string)"
public IWithType Start() { /*implementation here*/ }
Fildor
  • 14,510
  • 4
  • 35
  • 67