HiveBrain v1.2.0
Get Started
← Back to all entries
snippetcsharpMinor

How to remove code duplication that difference only a few lines?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
duplicationremovedifferencefewthathowcodeonlylines

Problem

I have 2 methods that do almost the same things except a few lines of code. The sample is like below.

public void Method1()
{
    DoX();

    if (value)
    {
        var input = GetA();
        DoA1();
        DoA2(input);
    }

    DoY();
}

public void Method2()
{
    DoX();

    if (value)
    {
        var input = GetB();
        DoB(input);
    }

    DoY();
}


I have two questions for this code.

  1. Is it a good idea to remove code duplication is this case?



  1. How to remove the duplication without make it harder to read the code

Solution

Based on your code as that is what we are reviewing a couple of suggestions.

  • Pass in a delegate that handles the changeable part



  • Use Template method pattern to implement the changing parts



  • Use composition and DI to inject the different elements



Example: Using delegates

private void DoMethod12(Action doMyAction)
{
    DoX();
    doMyAction();
    DoY();
}

public void Method1()
{
    DoMethod12(_ =>
    {
        var input = GetA();
        DoA1();
        DoA2(input);
    });
}

public void Method2()
{
    DoMethod12(_ =>
    {
       var input = GetB();
       DoB(input);
    });
}


Example 2: Template pattern

public abstract class MyDo
{
    protected abstract DoMyAction1();
    protected abstract DoMyAction2();

    public void Method1()
    {
        DoMethod12(doMyAction);
    }

    public void Method2()
    {
        DoMethod12(doMyAction2);
    }

    private void DoMethod12(Action doMyAction)
    {
        DoX();
        doMyAction();
        DoY();
    }
    private void DoX()
    {
    }
    private void DoY()
    {
    }
}

public class MyDoer : MyDo
{
    protected override DoMyAction1()
    {
           var input = GetA();
           DoA1();
           DoA2(input);
    }

    protected override DoMyAction2()
    {
       var input = GetB();
           DoB(input);
    }
}


Example 3: DI and composition

public interface IMyDoer
{
    void MyMethod1();
    void MyMethod2();
}

public class MyDoer
{
   private MyDoer _doer;

   public MyDoer(IMyDoer doer)
   {
      _doer = doer;
   }

    public void Method1()
    {
        DoMethod12(_doer.MyMethod1);
    }

    public void Method2()
    {
        DoMethod12(_doer.MyMethod2);
    }

    private void DoMethod12(Action doMyAction)
    {
        DoX();
        doMyAction();
        DoY();
    }

    private void DoX()
    {
    }
    private void DoY()
    {
    }
}


These written in notepad so no guareentee on exact syntax although hopefully they can give some ideas.

Code Snippets

private void DoMethod12(Action doMyAction)
{
    DoX();
    doMyAction();
    DoY();
}

public void Method1()
{
    DoMethod12(_ =>
    {
        var input = GetA();
        DoA1();
        DoA2(input);
    });
}

public void Method2()
{
    DoMethod12(_ =>
    {
       var input = GetB();
       DoB(input);
    });
}
public abstract class MyDo
{
    protected abstract DoMyAction1();
    protected abstract DoMyAction2();

    public void Method1()
    {
        DoMethod12(doMyAction);
    }

    public void Method2()
    {
        DoMethod12(doMyAction2);
    }

    private void DoMethod12(Action doMyAction)
    {
        DoX();
        doMyAction();
        DoY();
    }
    private void DoX()
    {
    }
    private void DoY()
    {
    }
}

public class MyDoer : MyDo
{
    protected override DoMyAction1()
    {
           var input = GetA();
           DoA1();
           DoA2(input);
    }

    protected override DoMyAction2()
    {
       var input = GetB();
           DoB(input);
    }
}
public interface IMyDoer
{
    void MyMethod1();
    void MyMethod2();
}

public class MyDoer
{
   private MyDoer _doer;

   public MyDoer(IMyDoer doer)
   {
      _doer = doer;
   }

    public void Method1()
    {
        DoMethod12(_doer.MyMethod1);
    }

    public void Method2()
    {
        DoMethod12(_doer.MyMethod2);
    }

    private void DoMethod12(Action doMyAction)
    {
        DoX();
        doMyAction();
        DoY();
    }

    private void DoX()
    {
    }
    private void DoY()
    {
    }
}

Context

StackExchange Code Review Q#18379, answer score: 8

Revisions (0)

No revisions yet.