2

所以我有一个简单的程序,粗略地点击一个按钮并执行一个任务,没什么花哨的,非常简单。现在,我为它添加了更多功能任务。它执行大约 5 种不同的主要更复杂的任务。该任务几乎没有输入,例如处理插入名称、地址、电话号码等的常见类/命名空间示例。该任务更像是设置您希望如何执行的设置(选中/取消选中复选框)任务,然后单击按钮来执行它。代码已经失控。所以我现在正在努力组织它。我是自学成才的,所以我遇到了一些麻烦,但这是我迄今为止对组织的想法。任何有关组织此活动的正确方法的评论将不胜感激。

  • 命名空间命名空间名称
    • 类 task1Name
      • 任务1的方法
    • 类 task1Name
      • 任务2的方法
    • 类 task2Name
      • 任务3的方法
    • 类 task3Name
      • 任务4的方法
    • 类 task5Name
      • 任务5的方法

现在我还有一个用于程序的窗体和另一个用于弹出设置窗口的窗体。最大的问题是这些到底适合哪里?公共部分类类名:形式?此设置是否允许不同任务类中的方法仍与表单 webbrowser 控件交互?该表单有几个 webbrowser 控件,任务在 webbrowser 控件中执行。

我想总的来说,我只是想找到管理代码和正确设置/构造代码的最佳方法。通过阅读这篇如何在 C# 中使用单独的 .cs 文件?也许我只是坚持使用一个类/文件,因为该任务涉及 Windows 形式的网络浏览器。

我一直在查看http://msdn.microsoft.com/en-us/library/w2a9a9s3%28v=vs.100%29.aspx以及代码示例下方列出的相关部分

4

1 回答 1

2

将你的程序分解成更易于维护的块——重构的艺术——可能是一个非常具有挑战性但也是非常有益的编程部分。就像@Keith 说的,你会边做边学。

最重要的建议是以小的、独立的步骤进行重构。

您可以通过多种方式开始此操作。如果您需要详细的建议,了解某些代码的外观会有所帮助。例如,什么是“任务”方法的签名(它们的名称、参数和返回类型)以及它们如何与“设置”交互。

这是我要提出的一个建议。单一职责原则建议单独的任务应该在单独的类中(通常,这意味着它们应该在单独的文件中 - 但这对编译器根本不重要,它只是为了可读性)。如果任务在不同的类中,他们将需要一种方法来了解表单上的设置是什么。但是这些任务并不关心设置在表单上的事实——它们只需要设置的值。因此,创建一个包含表单中所有设置的数据结构。然后,在表单类中编写一个方法,从控件中读取所有设置,这样您就可以将所有设置放在一个地方。然后,在每个任务按钮的按钮单击处理程序中,只需调用该方法来获取设置,并将设置传递给您尝试运行的特定任务。快!

然后您的代码将如下所示:编辑:我忘记了需要将 WebBrowser 控件传递给任务。固定的。

// Note: All classes and structs go in the same namespace, but each goes in its own .cs file.

// Use a struct, rather than a class, when you just need a small set of values to pass around
struct MySettings
{
    public int NumberOfWidgets { get; set; }
    public string GadgetFilename { get; set; }
    public bool LaunchRocket { get; set; }
}

partial class MyForm
{
    // ...constructor, etc.

    private void ButtonForTask1_Clicked(object sender, EventArgs e)
    {
        var settings = ReadSettingsFromControls();
        var task1 = new Task1(settings);
        task1.DoTheTask(ref this.WebBrowserControl1);
    }

    private void ButtonForTask2_Clicked(object sender, EventArgs e)
    {
        var settings = ReadSettingsFromControls();
        var task2 = new Task2(settings);
        task2.DoTheTask(ref this.WebBrowserControl1);
    }

    // ... and so on for the other tasks

    private MySettings ReadSettingsFromControls()
    {
        return new MySettings
        {
            NumberOfWidgets = int.Parse(this.txt_NumWidgetsTextBox.Text),
            GadgetFilename = this.txt_GadgetFilenameTextBox.Text,
            LaunchRocket = this.chk_LaunchPermission.Checked
        };
    }
}

class Task1
{
    // Readonly so it can only be set in the constructor.
    // (You generally don't want settings changing while you're running. :))
    private readonly MySettings _settings;

    public Task1(MySettings settings)
    {
        _settings = settings;
    }

    public void DoTheTask(ref WebBrowser browserControl)
    {
        // TODO: Do something with _settings.NumberOfWidgets and browserControl
        // You can use private helper methods in this class to break out the work better
    }
}

class Task2 { /* Like Task1... */ }

希望有帮助!同样,如果您发布一些示例代码,您可能会在如何重构它方面获得更好的建议。

于 2012-06-07T05:30:18.237 回答