我已经用C#编程了一段时间了.我最近编写了一个例程,它发生在我身上,这是我第一次(我记得)故意使用裸代码块(即没有前面的控制流语句).代码看起来像这样:
//... var output = source.GetRawOutput(); { var fooItems = FooSource.GetItems(); output = TransformA.TransformOutput(output, p => { GetFooContent(p, fooItems.GetNext()); }); } { var barItems = BarSource.GetItems(); output = TransformB.TransformOutput(output, p => { GetBarContent(p, barItems.GetNext()); }); } return output;
我通过这种方式构建代码主要是作为一个完整性检查,我不会意外地引用错误的变量(即混合barItems和fooItems).我还发现代码更具可读性.我当然可以将代码分解为三种不同的方法,但我觉得在这种情况下有点矫枉过正.
你在代码中使用裸代码块吗?为什么或者为什么不?
如果你看一下代码,那两个块就非常相似.我敢打赌他们可以重构成一个块.
虽然这听起来不像答案,但确实如此.我认为一般来说,如果你觉得使用这样的大括号的愿望,你正在处理一种情况,通过分解另一种方法或重构碎片可以更好地处理.
总的来说无论如何.
具体的答案 - 不,一旦我擅长OO并限制我在一个单位做多少工作,我从未想过他们可能是个好主意.
编辑:使用相似的代码,它必须相当容易重构.我会试试一个重构器.对不起,如果我的语法错误,我真的不做c#而且Java没有闭包.
output = transform(FooSource, TransformA); output = transform(BarSource, TransformB); // I know output is overwritten, but // it is in the askers' example as well transform(var itmSource, var transform) { var output=source.GetRawOutput(); // Sorry, you never said where source came from. var items = itmSource.GetItems(); output=transform.TransformOutput(output, p => { GetContent(p, items.GetNext()); // GetContent may need to be passed in // you didn't say where those calls came from. // See comments below }); } return output; }
像这样的重构不会节省太多的输入,但它们会显示一些很好的模式 - 比如FooSource和TransformA之间的关系(以及可能的getContent调用) - 它们应该存储在单个对象中的可能性很小并且该对象应该被传入,或类似的东西.(从这个片段中很难说,通常重构需要比你给出的代码更广泛的视图)
请注意,它们还会强制您考虑GetFooContent和GetBarContent.我敢打赌你是一品脱啤酒,它们是如此相似,以至于它们可以被分解为一个方法调用,一个变量或两个传入或两个兄弟类中的方法.
由于这种关系总是出现并总是改进你的类中的其他代码的方式,我相信这些重构是绝对强制性的,做这种重构比任何教我真正的OO更重要.