【问题标题】:Too much code in a class, but not sure how to go about reducing it类中的代码太多,但不知道如何减少它
【发布时间】:2014-01-09 16:30:14
【问题描述】:

我编写了一个应用程序,用于在工作中检查多个 POS 设备(计算机)是否在线并回复网络 ping,然后根据 ping 响应将相应的矩形着色为红色或绿色。它有 10 条“线”,每条都能够显示一个主服务器和多达 60 个 pos 设备和一个可以填充站点编号的文本框。然后,当您单击 go 时,它将读取 2 个 .ini 文件以查找站点 IP 方案和设备数量及其地址,以便可以对每个设备进行 pung(或 ping 大声笑)。我附上了应用程序的屏幕截图,这可能有助于解释我做了什么?!

然后我可以使用我的应用程序查看一个或多个站点的计算机是否在线,例如,如果我对计算机运行远程升级,我可以看到它们都停止回复(框变为红色)并重新启动(框再次变绿)然后我可以很容易地知道,一旦所有更新都完成并且计算机都重新启动了。我的问题是我的代码(IMO)太长并且可能没有它可能的效率(60k 行!)。

对于 10 行中的任何一行或所有行,每行后面的代码都是相同的,除了对象和变量名称等(即第一个“回复”矩形称为“rectSt1Pos1”(表示矩形 Shape-Store1-Pos1) ,然后是 'rectSt1Pos2' 等等,直到 '...Pos60',并重复所有 10 行(最后是 'rectSt10Pos60'))。这意味着我必须绘制 610 个单独的框(因为我对动态绘制它们不太自信),对此我很满意,但我已经完成了一些事情,比如在课程开始时初始化所有变量(没有分配值)但超过 1200 行只是为了为每个可能被打孔的设备(10 个站点,每个站点都有一个主服务器,加上每个站点最多 60 个 POS,每个设备一个成功和 1 个失败计数器)有一个成功和失败的回复计数器= 1220 个 int 值来存储 ping 计数!)

好的,希望对应用程序的解释就足够了,至于我的问题,即我的应用程序代码(其中大部分在一个类中(我唯一的其他类是阅读 ini文件))刚刚达到 60,000 行(是的,有六万行!!)。这基本上是我认为应该的大小的 10 倍,我确信我应该能够减少这个,但我不知道如何开始考虑重构代码!!。

另外,我认为我应该能够在可以调用的通用类或方法中为每一行执行所有操作,但我不确定如何做到这一点,因为每一行都是矩形和地址等。是不同的,需要跨线程更新(我;对跨线程没问题;))

所以总而言之,有没有人对如何减少代码大小有任何建议?或者有一个 60,000 多行的类是否可以?编译时的应用程序约为 1.8Mb 并使用大约 40Mb 的内存, 15-25 个线程和 400-1100 个句柄...这是可以接受的开销吗?

对此的任何建议、意见或帮助将不胜感激。如果有帮助,我也可以发布代码 sn-ps 并且由于尚未发布屏幕截图(因为我显然没有足够的声望点!)如果需要,我可以将其托管在其他地方。

非常感谢您的宝贵时间,如果有什么不太清楚的地方请询问(但不要全部说出来哈哈!)

干杯,

丹。

【问题讨论】:

  • 对不起,我直到现在才看到这条评论!,我正在使用 C# :)
  • 您将获得更多帮助(我用 C# 标签标记了您的问题)

标签: c# refactoring simplify


【解决方案1】:

你需要使用子程序:

  • 一个“处理线”子程序
  • 一个“手柄设备”子程序

调用“handle line”子程序10次。

每行调用“handle device”子例程 60 次。

不要复制粘贴相同的代码:在复制粘贴的行周围使用extract method,这样它们只会出现一次(在子例程中)而不是被复制。

类似这样的:

class Device
{
  // device properties here
  int deviceState;
}

class Line
{
  // line properties here
  int lineState;
  // devices associated with this line
  Device[] devices;
  // constructor
  Line()
  {
    devices = new Device[60];
  }
}

class Main
{
  List[] lines;
  Main()
  {
    lines = new Lines[10];
    for(int i = 0; i < 10; ++i)
      HandleLine(i, line[i]);
  }
  void HandleLine(int lineNumber, Line line)
  {
    // get line status
    line.status = getLineStatus(lineNumber);
    // handle devices on this line
    for(int i = 0; i < 60; ++i)
      HandleDevice(lineNumber, i, line.devices[i]);
  }
  void HandleDevice(int lineNumber, int deviceNumber, Device device)
  {
    // get device status
    device.status = getDeviceStatus(lineNumber, deviceNumber);
  }
}

以上是用于说明辅助类(线路和设备)的伪代码。使用 C#,您可能希望使用 System.Collections.Generic.List 而不是数组。

此外,HandleLine 功能可以是 Line 的方法而不是 Main。它甚至可以是 Line 类的构造函数。

【讨论】:

  • 感谢您的回复 :) - 好的,那么“子例程”是同一类中的附加方法吗? - 因为如果我添加一些子例程来初始化变量(字段),这会将其从我更新所述变量并导致错误的“当前上下文”中删除......这是否意味着它们必须在外部声明方法?
  • 哦,我明白了,例如,如果我想改进我之前提到的 ping 计数器,而不是在我的主类顶部初始化 1220 int 变量,我可以创建一个新类我将调用 pingCounter,然后添加如下公共属性: public static int st1MfsCountSucc { get;放;对于我要初始化并添加“pingCounter”的每个计数器。在主类中对这些计数器的任何引用之前?...
  • @RatMonkey 没错,是的,类似的东西(如果没有看到您的代码,很难提供更多细节)。
  • 我会在这里发布,但我认为 60k 行对于论坛来说可能有点大?!大声笑,我将创建 PingCounter 类,该类将从代码中删除大量行。我在回复中看到了您的代码,看起来应该很有帮助。我将尝试一下并修改现有代码,甚至可能将 pingCounter 放入行属性或其他东西中。完成后我会在这里回复,让您知道我的进展情况:D - 非常感谢您迄今为止的帮助!
  • 一旦它足够小可以发布,请尝试codereview.stackexchange.com,这可能是一个更好的站点来审查/重构现有/工作实现。和/或,发布仅支持两条线路和两种设备的版本。
【解决方案2】:

一个文件中有 60,000 多行! 使用方法/函数/子例程/宏来抽象输入和输出。

如果参数因某些逻辑而不同(例如每次 +1),也可以考虑使用循环而不是重复相同的命令。

【讨论】:

  • 我想做一个循环来声明字段/变量,但我不知道如何(如果有的话)我可以从现有字符串中声明一个变量名。 IE。 'int st[1st loop count figure]Pos[2nd loop count figure]Succ' 其中方括号 [] 中的文本是从调用循环传递的 int 变量...?
  • 请将编程语言添加到您的问题/描述中。
  • @RatMonkey 您要查找的内容称为“an array”(或者在 C# 中人们经常使用 a so-called List instead)。
猜你喜欢
  • 2021-08-22
  • 2020-12-19
  • 1970-01-01
  • 2020-10-16
  • 2012-01-09
  • 2018-08-09
  • 2023-02-03
  • 2018-02-11
  • 2016-04-24
相关资源
最近更新 更多