在构建器模式中管理顺序的首选方法是什么?

Sam*_*l G 5 c# nunit design-patterns

我创建了一个流畅的构建器样式模式,用于帮助我加载测试数据.某些方法的顺序很重要,并且想知道管理正确序列的首选方法是什么.

我现在有以下内容:

using NUnit.Framework;

[TestFixture]
public class DataBuilderTests
{
    [Test]
    public void Can_NAME()
    {
        new DataLoader()
            .Start() // must be called first
            .Setup() // then called next
            .LoadEmployees() // optional order not NB
            .LoadProducts() // optional order not NB
            .StartCleanup() // begin cleanup
            .CleanupEmployees() // optional order not NB
            .CleanupProducts() // optional order not NB
            .End();
    }
}

public class DataLoader
{
    public DataBuilderSetup Start()
    {
        return new DataBuilderSetup(this);       
    }
}

public class DataBuilderSetup
{
    private readonly DataLoader _dataLoader;

    public DataBuilderSetup(DataLoader dataLoader)
    {
        _dataLoader = dataLoader;
    }

    public DataBuilderOptions Setup()
    {
        // do setup
        return new DataBuilderOptions(_dataLoader);
    }
}

public class DataBuilderOptions
{
    private readonly DataLoader _dataLoader;

    public DataBuilderOptions(DataLoader dataLoader)
    {
        _dataLoader = dataLoader;
    }

    public DataBuilderOptions LoadEmployees()
    {
        // load
        return this;
    }

    public DataBuilderOptions LoadProducts()
    {
        // load
        return this;
    }

    public DataBuilderCleanupOptions StartCleanup()
    {
        return new DataBuilderCleanupOptions(_dataLoader);
    }
}

public class DataBuilderCleanupOptions
{
    private readonly DataLoader _dataLoader;

    public DataBuilderCleanupOptions(DataLoader dataLoader)
    {
        _dataLoader = dataLoader;
    }

    public DataBuilderCleanupOptions CleanupEmployees()
    {
        // cleanup
        return this;
    }

    public DataBuilderCleanupOptions CleanupProducts()
    {
        // cleanup
        return this;
    }

    public DataLoader End()
    {
        return _dataLoader;
    }
}
Run Code Online (Sandbox Code Playgroud)

dan*_*uch 6

在 Java 中(C# 及其多重继承不应使其有任何不同),您可以这样做:

声明一组仅包含一个方法的接口:

Interface DoFirstThing { // could be renamed to "BuilderOnStart" or "BuilderStartingState"
    DoSecondThing doFirst();
}

Interface DoSecondThing {
    DoLastThing doSecond();
}

Interface DoLastThing {
    BuilderReady doLast();
}

Interface BuilderReady {
    Result build();
}

class BuilderWithForcedSequence implements DoFirstThing, DoSecondThing, DoLastThing, BuilderReady {

     // implement all

}
Run Code Online (Sandbox Code Playgroud)

最后,您需要一些工厂或工厂方法来设置该构建器的初始状态:

public DoFirstThing createNewBuilderWithForcedSequence(requiredParameters){
    return new BuilderWithForcedSequence(requiredParameters);
}
Run Code Online (Sandbox Code Playgroud)

这将产生 Builder,强制对构建方法进行排序(它们应该重命名为doThat有意义的名称),只能调用doFirst(),之后doSecond()......依此类推,直到最终状态,此时将使用build()方法构建对象。

Result result = builder.doFirst().doSecond().doLast().build();
Run Code Online (Sandbox Code Playgroud)


编辑:
哎呀,这正是你的方法:)


Cha*_*ion 1

首选方法是不惜一切代价避免它。设计您的构建器,使其清楚需要做什么。

ObjectBuilder
.Init()
.Optional1()
.Optional3()
.Optional2()
.ToObject()
Run Code Online (Sandbox Code Playgroud)

如果需要先发生某些事情,请在构造函数或工厂方法中执行此操作。然后始终有一种方法可以完成构建过程、清理等。