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?

+3


source to share


2 answers


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.

+4


source


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

      

0


source







All Articles