Search code examples
c#refactoringcode-duplication

Refactoring c# : How to remove duplicated code when properties to update differ in each case


After hacking about for a little while on a prototype I've ended up with number of methods that update boolean flags on an object and then update interface and do some processing based on the new value. These are pretty much all the same - but the value they update is different

for example - imagine we have a bunch of colored boxes to update - I might have some methods that look like this:

        protected void SetBlueBoxVisibility(bool blueBoxVisibility)
    {
        Project project = LoadProject();
        project.ShowBlueBox = blueBoxVisibility
        ReDrawSomeThings();
        CalcualteSomeStuff();
        Project.UpdateBoxStatus();
        SaveProject(project);
        ShowBlueBoxPanel(blueBoxVisibility);
        RaiseStatusUpdated();
    }

    protected void SetRedBoxVisibility(bool redBoxVisibility)
    {
        Project project = LoadProject();
        project.ShowRedBox = redBoxVisibility
        ReDrawSomeThings();
        CalcualteSomeStuff();
        Project.UpdateBoxStatus();
        SaveProject(project);
        ShowRedBoxPanel(redBoxVisibility);
        RaiseStatusUpdated();

    }       

Now, obviously - most of that stuff is repeated - which is a pain when I come to change anything. Particularly if I end up with twenty different box colors rather than just two!

I was thinking that there must be a way to strip out the code that changes and gather the stuff that's the same in a more generic method - but I'm having trouble getting to quite how to do that.

I've heard of closures - but I haven't gotten my head around them enough to know if they would help here.

I was thinking possible the following might be on the right line - but I'm I don't know how to tell the generic method which property to operate on - [Project Variable To Update]

        protected void SetRedBoxVisibility(bool redBoxVisibility)
    {
        SetGenericBoxVisibility([Project Variable To Update],redBoxVisibility)
        ShowRedBoxPanel(redBoxVisibility);
        RaiseStatusUpdated();   
    }

    protected void SetBlueBoxVisibility(bool blueBoxVisibility)
    {
        SetGenericBoxVisibility([Project Variable To Update],blueBoxVisibility)
        ShowBlueBoxPanel(blueBoxVisibility);
        RaiseStatusUpdated();   
    }

    protected void SetGenericBoxVisibility([Project Variable To Update], boxVisibility)
    {
        Project project = LoadProject();
        project.**[Project Variable To Update]** = boxVisibility
        ReDrawSomeThings();
        CalcualteSomeStuff();
        Project.UpdateBoxStatus();
        SaveProject(project);
    }

Any pointers as to how to handle this kind of thing would be useful :)


Solution

  • Well, you could extract it like this:

    protected void SetGenericBoxVisibility(Action<Project> propertySetter,
                                           Action<bool> panelShower,
                                           bool boxVisibility)
    {
        Project project = LoadProject();
        propertySetter(project);
        ReDrawSomeThings();
        CalculateSomeStuff();
        Project.UpdateBoxStatus();
        SaveProject(project);
        panelShower();
        RaiseStatusUpdated();
    }
    

    Then:

    protected void SetBlueBoxVisibility(bool blueBoxVisibility)
    {
        SetGenericBoxVisibility(project => project.ShowBlueBox = blueBoxVisibility,
                                () => ShowBlueBoxPanel(blueBoxVisibility));
    }
    
    protected void SetRedBoxVisibility(bool redBoxVisibility)
    {
        SetGenericBoxVisibility(project => project.ShowRedBox = redBoxVisibility,
                                () => ShowRedBoxPanel(redBoxVisibility));
    }
    

    It's not terribly nice, admittedly...