2012-06-07 35 views
2

所以我有一个简单的程序,大致点击一个按钮,它执行任务,没有什么幻想,非常简单。现在,我添加了很多功能来完成它。它执行大约5个不同的主要更复杂的任务。就像处理插入名称,地址,电话号码等的常见类/名称空间示例一样,该任务的意义不大。该任务更像是设置设置(选中/取消选中复选框)以确定要如何预制该任务,然后单击按钮以预制它。代码已经失控。所以我现在试图组织它。我是自学成才的,所以我遇到了一些麻烦,但这是我到目前为止组织的想法。任何意见关于正确的方式来组织这将不胜感激。C#正确的程序结构

  • 命名空间namespaceName
    • 类task1Name
      • 方法TASK1
    • 类task1Name
      • 方法TASK2
    • 类task2Name
      • 方法TASK3
    • 类task3Name
      • 方法task4
    • 类task5Name
      • 方法任务5

现在我也有程序在Windows窗体和其他窗口形成弹出设置窗口。最大的问题是它们在哪里完全适合?公共部分类className:Form?此设置是否允许不同任务类中的方法仍然与表单浏览器控件进行交互?该表单有几个web浏览器控件,并且该任务在web浏览器控件中进行制定。

我想一般我只是试图找到管理代码和正确设置/结构代码的最佳方式。从阅读这个How to use separate .cs files in C#?也许我只是坚持一个类/文件,因为任务涉及Windows窗体的浏览器。

我一直都在http://msdn.microsoft.com/en-us/library/w2a9a9s3%28v=vs.100%29.aspx和下面的代码示例

+0

这些任务实际上是相关的吗?或者你能把这个东西切成几个有重点的节目吗? – bluevector

+0

任务是分开的,因为在彼此之间不互相沟通,但总体而言,我想你可以说。我的目标是设置任务的设置,然后将其最小化到系统托盘,并让它在一天中在后台运行任务。我真的只是试图找到一个更好的方式来管理代码,也许? – Delirious

+0

它是混乱或用户体验的代码?一个会产生另一个。这是一个你只关心的实用工具吗? – bluevector

回答

2

程序打破了成更易于维护的块中列出的相关部分 - 的艺术重构 - 可以是一个非常具有挑战性的,也是非常有意义的,编程的一部分。就像@凯斯说的,你会通过做法来学习。

最重要的建议是小型自包含步骤的重构。

有几种方法可以启动此功能。如果你需要详细的建议,这将有助于了解一些代码的样子。例如,什么是“任务”方法签名(它们的名称,参数和返回类型)以及它们如何与“设置”进行交互。

这是我会提出的一个建议。 单责任原则表明,单独的任务应该在单独的类中(通常,这意味着它们应该位于单独的文件中 - 但对编译器无关紧要,它只是为了便于阅读)。如果这些任务在不同的类中,他们将需要一种方法来了解表单上的设置。但是这些任务并不关心设置在表单上的事实 - 他们只是想要设置的值。因此,创建一个包含表单中所有设置的数据结构。然后,在窗体类中编写一个单一的方法,读取控件中的所有设置,这样你就可以在一个地方完成所有的设置。然后,在每个任务按钮的按钮单击处理程序中,只需调用该方法即可获取设置,并将设置传递给您尝试运行的特定任务。普雷斯托!

你的代码会看起来像这样:编辑:我忘了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... */ } 

希望帮助!同样,如果你发布了一些示例代码,你可能会得到更好的关于如何重构它的建议。

+0

第二个最重要的建议是***使用源控制***来跟踪你所做的更改。如果您尚未这样做,请立即访问http://hginit.com/01.html。这是免费的开源Mercurial源代码管理系统的一个很好的教程,你可以从http://tortoisehg.bitbucket.org/获得Windows版本。 –

+0

感谢您的评论!我决定继续并开始组织和分解代码。此外,我还没有使用源代码管理,所以这也是一个很好的补充。我已经在不同的地方获得了5份该节目的副本,所以这将是一个很好的方法来保持这一点。 – Delirious

+0

不客气!如果您在重构期间遇到任何问题(与代码或源代码控制相关),请告诉我们。请记住投票并接受有用的评论和答案。 :) –