我正试图在工作中的一个应用程序中重写极其丑陋的类。在我们的一个类中,有数百行代码确保某些类的初始化和重新初始化。目前,这是以可怕的蛮力-y方式完成的,在这种方式下,您编写init代码并手动将其复制到re-init part (因为它们非常相似)。
正因为如此,我开始将其重写为委托列表的形式,然后在两个位置都使用一个参数调用(bool isReinit)。然后我注意到大多数委托也是相同的,因为90%的类的初始化过程是相同的。这意味着我应该能够创建一些默认的初始化函数来极大地简化代码。目前我创建了类似这样的东西:
https://dotnetfiddle.net/RVS5UT
我还创建了类CustomInitializer,它实现了IInitializer,并且只接受一个Func作为参数,并在初始化中运行它,用于初始化有很大不同的情况。
现在,这个简化的和匿名的工作代码,但它是有效的。问题是整个方法非常笨拙,构造函数签名丑陋得像地狱一样。有什么方法可以简化这一点吗?我找不到任何对我有帮助的模式或方法?任何迈向更好代码的步骤都是受欢迎的,也许我只是错过了一些东西。
还有另一个问题。我想出的一个解决方案是存储属性对(var1a + var1b,var2a+var2b,..)并将其直接传递给Initialize方法。但这将意味着移动属性,遗憾的是,这在目前是不可能的,因为文件有超过18k行,代码审查者会因为一个方法的重构而更改其中的三分之一(即使是一个很长的方法)。我需要保留目标属性(var1a、var1b、var2a、..)他们现在在哪里。这也可能意味着没有优雅的方法来解决这个问题。
我使用的是.NET 4.0、C# 5.0
编辑:我没有访问初始化类型的权限(另一个愚蠢的问题)
谢谢你的帮助。
发布于 2016-05-30 21:11:24
该文件有超过18k行
哇,看起来很有趣。
尝试改进它绝对是件好事。相信我,不管你的同事怎么想,这里除了重构没什么可做的,除非这段代码不需要进化。
但是,在我看来,你似乎走在复杂的道路上,试图变得枯燥,而不是试图表现出来。让StandardInitializer和CustomInitializer管理lambda的想法非常复杂。类的初始化应该在它负责初始化的类中。如果某些行为确实是共享的,则它们可能共享一个基类或一个协作类。
我推荐你在Working Effectively With Legacy Code上讨论这个话题。正如您将看到的,并且可能已经知道,第一个关键点是进行测试。请不要试图在没有测试工具的情况下重构这样的类。否则你会引入回归,你会感到沮丧,你的同事会在他们的愿景中得到安慰,在这里什么都不能做,除非打破一切。
不要忘记,如果测试很难创建,那是因为糟糕的代码,而不是因为测试成本很高。糟糕的代码代价很高。
在一些测试保护了你之后,试着从责任和生命周期的角度来思考。例如,在WPF应用程序中,拥有“可初始化”的ViewModel是一个常见的问题,因为它们会执行一些异步web服务调用来初始化自己。
在这种情况下,负责给定ViewModel的生命周期的对象也有初始化它的责任。如果它管理几个Initializable视图模型,那么这种代码就很好:
foreach (var initializable in initializables)
{
initializable.Initialize();
}但是,无论您选择哪种解决方案,请在Initialize和Reinitialize之间保持清晰的分离(如果它们有共同之处,请让它们调用一个内部共享函数)。写像这样的东西是一个非常糟糕的想法:
init.Initialize(true);它清楚地说明了Initialize函数的行为将根据布尔值的不同而改变。如果你有两个行为,你应该有两个明确命名的函数。
https://stackoverflow.com/questions/37525944
复制相似问题