具有必填字段的 C# Step Builder

C# Step Builder with Required Field

我目前在 C# 应用程序中有一个非常基本的 Step Builder,它被创建为允许所有字段都是可选的,并且它为此工作得很好(尽管这使得它不是真正的 Step Builder)。

我知道可以将必填字段作为参数添加到构造函数中,但我想知道是否有一种方法可以将必填字段添加为一个步骤,以便它通过使用接口处理必填字段来保持步骤生成器的状态而不是构造函数参数。

我有一个笨蛋class来演示

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; }

}

然后步骤生成器(有点)为

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

    }

}

它适用于这些场景

// 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();

但它不适用于这种情况,因为 withType 应该成为必需的而不是可选的

// do not allow  : animal must have type
animal = new AnimalBuilder().start().build();

如果您想在构建器模式中强制设置特定选项,您可以通过不同的方式进行:

(列表可能不完整!)

  1. 您可以将它们作为 builder-creation 函数的参数。

您的案例示例:

public BuilderIfc Start(string type) { /*implementation here*/ }
  1. 您可以通过返回特定接口来强制执行“流”。
//     vv Next in flow _must be_ ".WithType(string)"
public IWithType Start() { /*implementation here*/ }