Design Pattern with Methods Returning Modified Parent
Suppose I have a class that looks like this:
class Data
{
public Data()
{
// Stuff
}
public void Process1()
{
// Stuff
}
public void Process2()
{
// Stuff
}
}
I have several use cases. The most common are the following:
var data = new Data();
data.Process1();
data.Process2();
One option I like to use requires me to change the class:
class Data
{
public Data()
{
// Stuff
}
public Data Process1()
{
// Stuff
return this;
}
public Data Process2()
{
// Stuff
return this;
}
}
Then I can use it like this:
var data = new Data().Process1().Process2();
To what design pattern, if any, does this style of writing classes belong?
source to share
A method on a fluent interface should, in my opinion, return a new instance of the original object with the state updated by this method. Otherwise it's easy to write misleading code.
Take this code for example:
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;
}
}
If I run 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);
I get:
3.66666666666667 3.66666666666667 3.66666666666667
However, if I write it like this:
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);
}
}
results
five eleven 1.66666666666667
And of course I can write var w = x.Times2Add1().Divide3();
which gives me 3.66666666666667
which I got above, but this time it makes more sense to me. It will become verifiable reliable code.
LINQ does it right - a call to .Where
, for example, an enumerated does not change the enumerated, but instead returns a new one. This is the best way to write a fluent interface.
When you see return this;
, even if this is a fluent interface, I consider it a code smell.
source to share
Take a look at the linker pattern here , it is used in the .net core starter class to create application configuration through the ConfigurationBuilder object, and they use the call chaining:
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();
}
source to share