在多年的职业生涯中,经常需要处理他人的代码。这让培养了一些非常有用的代码维护技能。然而,能够阅读他人的代码并不能减少处理糟糕代码时的挫败感。这种挫败感不仅来自于需要修复和扩展代码,还来自于试图弄清楚代码可能出错的地方,并且还要为这些错误背后的错误思考承担后果。
更糟糕的是,一些管理者会阻碍任何重构的努力,他们将重构视为镀金行为,认为这是浪费时间和资源,而这些资源本应该用于开发新功能和保持项目按当前计划进行。事实上,代码腐烂是头痛的主要来源,是无尽bug和计划延误的根源。不解决这个问题会危及项目,给团队带来不必要的压力。但还有其他问题,一些团队成员缺乏技术技能,也不愿意学习新技能。因此,他们对腐烂的代码感到满意,因为他们更了解它,任何变化都会给他们带来压力。
在这种情况下,必须秘密地进行重构,这意味着应用程序的架构将保持不变,但一些有问题的代码文件将被重构。保持公共签名和整体愚蠢的函数,这些函数做得太多,不能立即改变,否则会引起不满。
让看看代码,好吗?从一个呈现以下模式的方法集开始:
public XmlDocument ThisMethodDoesSomethingImportant(
string xmlString)
{
XmlDocument XmlOut = new XmlDocument();
string Error = "";
this.DoesSomething(out Error);
if (Error != "")
{
// Do Some Trace code here...
XmlOut.LoadXml("
这个类有很多方法,几乎所有的方法都是复制的;挑战在于删除大部分复制的代码,同时保持其形式,以便更容易维护。
解决方案是使用.NET 2.0中的委托,在3.5及以上版本中使用Lambda函数,但首先,需要将方法体与公共方法调用分开。
在.NET 2.0中:
private delegate XmlDocument DelegatedFunction(SomeBusinessClass business);
// Now this is the repeated pattern
public XmlDocument ThisMethodDoesSomethingImportant(
string xmlString)
{
DelegatedFunction function = delegate (SomeBusinessClass business)
{
// changed method here
return business.SomeMethod(xmlString);
};
return this.DoesSomethingBody(function);
}
private XmlDocument DoesSomethingBody(DelegatedFunction function)
{
XmlDocument XmlOut = new XmlDocument();
string Error = "";
this.DoesSomething(out Error);
if (Error != "")
{
// Do Some Trace code here...
XmlOut.LoadXml("
在.NET 3.5及以上版本中:
// Now this is the repeated pattern
public XmlDocument ThisMethodDoesSomethingImportant(
string xmlString)
{
Func
这些示例中所做的是将方法体(大部分共享代码)与初始版本分开,并将委托或匿名函数发送以处理代码的变化部分。公共方法现在只是一个创建委托并将其发送到方法体的门面。
如果方法签名中有更多的输入变量,这也很容易扩展。
public XmlDocument ThisMethodDoesSomethingImportant2(
string xmlString,
string par1,
int par2)
{
Func