重构 c#:当要更新的属性在每种情况下不同时如何删除重复的代码

发布于 2024-12-03 22:25:18 字数 2008 浏览 0 评论 0原文

在对原型进行了一段时间的修改之后,我最终得到了许多方法,这些方法可以更新对象上的布尔标志,然后更新接口并根据新值进行一些处理。这些几乎都是相同的 - 但它们更新的值是不同的

,例如 - 想象我们有一堆彩色框要更新 - 我可能有一些看起来像这样的方法:

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

    }       

现在,显然 - 大部分内容都是重复的 -当我要改变任何事情时,这是一种痛苦。特别是如果我最终得到二十种不同的盒子颜色而不是两种!

我在想,必须有一种方法可以去除更改的代码,并以更通用的方法收集相同的内容 - 但我很难弄清楚如何做到这一点。

我听说过关闭 - 但我还没有充分了解它们,不知道它们是否会在这里提供帮助。

我认为以下内容可能在正确的行 - 但我不知道如何告诉通用方法要操作哪个属性 - [要更新的项目变量]

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

任何指针如何处理这种事情会很有用:)

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 :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

徒留西风 2024-12-10 22:25:18

好吧,你可以像这样提取它:

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

那么:

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

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

不可否认,这不是非常好......

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...

凉墨 2024-12-10 22:25:18

我认为您可能遇到更大的问题 - 每个框一种更新方法根本不合适。您拥有 SetGenericBoxVisibility,但随后通过继续使用 Set*BoxVisibility 方法来撤消所有好的工作。我不知道你正在使用哪种技术 - 如果它是 WPF 查看 MVVM 那么你可以简单地更新你的 ViewModels。如果是 WinForms,您可能应该创建某种字典 - Dictionary; _boxLookup 其中 BoxType 是您定义的类型的枚举。然后,要设置框可见性,请执行 _boxLookup[BoxType.Red].Property = value; 操作,或者您可以使用采用 BoxType 参数来操作框的方法。

然而,更多的上下文将非常有用,因为即使该解决方案也不是理想的。移动一些其他代码或深入了解您正在使用多个盒子解决的问题的大局应该会带来更多的“啊哈”时刻。

I think you may have bigger problems - one method per box to update simply doesn't fit. You have SetGenericBoxVisibility but then undo any good work by continuing to have Set*BoxVisibility methods. I don't know which technology you're using - if it's WPF look into MVVM then you can simply update your ViewModels. If it's WinForms you should create some kind of dictionary perhaps - Dictionary<BoxType, Box> _boxLookup where BoxType is an enum of the types you define. Then to set box visibility, you do _boxLookup[BoxType.Red].Property = value; or you could have methods to manipulate a box take a BoxType parameter.

However, some more context would be very useful, since even that solution isn't ideal. Moving some other code or getting some insight into the bigger picture about the problem you are solving with multiple boxes should lead to a few more 'aha' moments..

怎会甘心 2024-12-10 22:25:18

我认为要真正重构它,您需要制作一个 IBox 界面。基本上,该接口充当契约,定义所有 Box 对象至少必须具有哪些方法和属性。

interface IBox {
 //your generic properties and method stubs
 Bool visibility;
}

现在,为每个“盒子”实现接口

class blueBox : IBox
{
 //here you will have your concrete implementations of the above methods and properties
public Bool visibility   {get; set;} // this doesn't make sense with auto getter setters. you would need to write your bluebox specific getter and setters

}

class redBox : IBox
{
//more concrete implementation

}


public myMethod_To_Do_Stuff(IBox myBox) { // see how I am passing the interface not the conrete classes

myBox.visibility = true;

}

I think to really refactor this you need to make an IBox interface. Basically, that interface acts as a contract defining what methods and properties all Box objects must have at the very least.

interface IBox {
 //your generic properties and method stubs
 Bool visibility;
}

Now, implement the interface for each of your 'boxes'

class blueBox : IBox
{
 //here you will have your concrete implementations of the above methods and properties
public Bool visibility   {get; set;} // this doesn't make sense with auto getter setters. you would need to write your bluebox specific getter and setters

}

class redBox : IBox
{
//more concrete implementation

}


public myMethod_To_Do_Stuff(IBox myBox) { // see how I am passing the interface not the conrete classes

myBox.visibility = true;

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文