Javid_p84
Javid_p84

Reputation: 868

remove duplicate code by passing a method or something?

I have two methods exactly like each other but just in a line imagine :

    public void ApplyHorizontalScale(int x, int Y)
    {
        // Code 1
        forecast.Formula = Method1(X, Y);
        // Code 2
    }


    public void ApplyVerticalScale(int x, int Y)
    {
        // Code 1
        forecast.Formula = Method2("Foo");
        // Code 2
    }


    int Method1(int x , int y)
    {
        return x+y;
    }

    int Method2(string s)
    {
        return Foo.Length;
    }

The problem is Code 1 and Code 2 have been repeated twice! how can I have something like :

public void ApplyScale(int x, int Y, WhichMethod)
{
        // Code 1
        forecast.Formula = WhichMethod();
        // Code 2
}

please notice that Method1 and Method2 have different signature and also one of them is accessing a private member.

Upvotes: 2

Views: 586

Answers (5)

vgru
vgru

Reputation: 51322

It seems that the common thing is that your "Formula" property needs to get an int value.

In that case, something as simple as this would do:

public void ApplyScale(int x, int Y, int value)
{
    // ...
    forecast.Formula = value;
    // ...
}

And then call it with a different value each time:

ApplyScale(x, y, x + y);
ApplyScale(x, y, Foo.Length);

If you want to lazy calculate this value, you can do it like this:

public void ApplyScale(int x, int Y, Func<int> formula)
{
    // ...
    forecast.Formula = formula();
    // ...
}

And then call it with a different lambda each time:

ApplyScale(x, y, () => x + y);
ApplyScale(x, y, () => Foo.Length);

I don't see a real benefit in the latter approach, so I would simply pass the value to the method (unless there is something else behind your question, that I didn't understand).

Upvotes: 1

Eric Liprandi
Eric Liprandi

Reputation: 5574

By introducing a 3rd method, you can refactor as follows:

public void ApplyHorizontalScale(int x, int Y) 
{ 
    DoWork(x,y, ()=>Method1(X,Y));
} 


public void ApplyVerticalScale(int x, int Y) 
{ 
    DoWork(x,y, ()=>Method2("Foo"));
} 

private void DoWork(int x, int y, Func<int> action)
{
     // Code 1
     forecast.Formula = action();
     // Code 2
}

int Method1(int x , int y) 
{ 
    return x+y; 
} 

int Method2(string s) 
{ 
    return Foo.Length; 
} 

Hope this helps.

Upvotes: 1

Steven Jeuris
Steven Jeuris

Reputation: 19130

You have plenty of different options. Which one is most suitable depends on your scenario.

  • Place Code 1 and code 2 in separate functions; this reduces the duplicate code to just two lines of duplicate code.

  • Pass an enum/boolean option parameter to the function. Based on this parameter you can check whether you have to call Method1 or Method2.

  • Use an abstract base class and use concrete implementations to supply Formula.

  • Pass around delegates.

Upvotes: 1

Vamsi
Vamsi

Reputation: 4263

This is one way to do it

public void ApplyScale(int x, int Y, bool isHorizontal)
{
    // Code 1
    if(isHorizontal)
    {
       forecast.Formula = Method1(X, Y);
    }
    else
    {
       forecast.Formula = Method2("Foo");
    }
    // Code 2
}

You can also use enum instead of the isHorizontal flag

Upvotes: 3

starskythehutch
starskythehutch

Reputation: 3338

ApplyVerticalScale and ApplyHorizontalScale are perfectly good methods - you don't need to combine them into one "God" ApplyScale public method.

You should refactor the internals of the method to call some private ApplyScale (or similar) method that contains Code1 and Code2 once, with each method passing whatever it needs to apply scale in that particular orientation.

Upvotes: 4

Related Questions