使用返回修改后的父级的方法设计模式



假设我有一个看起来像这样的类:

class Data
{
public Data()
{
// Stuff
}
public void Process1()
{
// Stuff
}
public void Process2()
{
// Stuff
}
}

我有几个如何使用它的选项。最常见的如下:

var data = new Data();
data.Process1();
data.Process2();

我喜欢使用的一种替代方法需要我修改类:

class Data
{
public Data()
{
// Stuff
}
public Data Process1()
{
// Stuff
return this;
}
public Data Process2()
{
// Stuff
return this;
}
}

然后我可以像这样使用它:

var data = new Data().Process1().Process2();

这种写作风格属于哪种设计模式(如果有的话(?

在我看来,流畅接口上的方法应该返回源对象的新实例,其状态由该方法更新。否则,很容易编写误导性代码。

以这段代码为例:

public class Data
{
public double Value { get; private set; }
public Data(double value) { this.Value = value; }
public Data Times2Add1()
{
this.Value = this.Value * 2.0 + 1.0;
return this;
}
public Data Divide3()
{
this.Value = this.Value / 3.0;
return this;
}
}

如果我运行这个:

var x = new Data(5);
var y = x.Times2Add1();
var z = x.Divide3();
Console.WriteLine(x.Value);
Console.WriteLine(y.Value);
Console.WriteLine(z.Value);

我得到:

3.66666666666667 3.66666666666667

3.66666666666667但是,如果我这样写:

public class Data
{
public double Value { get; private set; }
public Data(double value) { this.Value = value; }
public Data Times2Add1()
{
return new Data(this.Value * 2.0 + 1.0);
}
public Data Divide3()
{
return new Data(this.Value / 3.0);
}
}

结果是

5 11

1.66666666666667当然,我可以写var w = x.Times2Add1().Divide3();,这给了我上面得到的3.66666666666667,但这一次对我来说更有意义。它成为可测试的健壮代码。

LINQ 可以正确执行此操作 - 例如,在可枚举对象上调用.Where不会更改可枚举项,而是返回一个新枚举项。这是编写流畅界面的最佳方式。

当你看到return this;,即使这是一个流畅的界面,我也会认为它是代码气味。

在此处查看构建器模式,它在 .net core 启动类中用于通过 ConfigurationBuilder 对象创建应用的配置,并且它们使用链式调用:

public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", 
optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", 
optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}

最新更新