让我们说我们有一个课程中有一些方法,其中至少有一个方法相当复杂:
class Example {
public function Example()
{
}
private function complexFunction():void
{
//Do this
//And do that
//And of course do that
//and do not forget that
}
private function otherImportantFunction():void
{
//Do something
}
//[...]
}
现在“complexFunction()”已经发展得相当长,也有点复杂。因此,提高可读性的一个好处是在较小的子函数中拆分“complexFunction()”。我通常这样做:
class Example {
public function Example()
{
}
private function complexFunction():void
{
doThis();
doThat();
andOfCourseDoThat();
andDoNotForgetThat();
}
private function doThis():void
{
//Do This
}
private function doThat():void
{
//Do That
}
private function andOfCourseDoThat():void
{
//And of course do that
}
private function andDoNotForgetThat():void
{
//And do not forget that
}
private function otherImportantFunction():void
{
//Do something
}
//[...]
}
但到现在为止,这个类已经淹没在次要函数中,其唯一目的是在“complexFunction()”内部调用一次。这种“分裂”更频繁地进行,并且很难发现所有这些辅助函数之间的重要方法。
至少这是我一直在发生的事情,而且清晰度确实会受到影响。这让我想知道你是否知道解决这种困境的方法?当然有办法或'最佳实践'来处理这个问题? 我梦想着一种将功能组合在一起的方法,或者将次要功能从属于高级功能,而无需为此目的创建一个全新的类。或者它是如何完成的?
答案 0 :(得分:0)
将一个大函数拆分为多个函数是正确的。如果它不是AddOne()
而不是value++
。特别是你可能会更频繁重复的功能也可以使用。
当你的课程充满了多种功能(或长功能)时,重新考虑你的课程的作用可能是个好主意。尽量让你的课程注定一个科目。例如,一个类的好主意是使其与用户相关。可以在那里完成创建或删除用户之类的事情。甚至将用户匹配到例如他们拥有的汽车也可以在那里完成。但是不要在User-class中包含保存或删除Cars的函数。保存为另一个班级。
在这种情况下,您的Example-class将具有User-class和Car-class的实例。如果它看起来像这样,那你就是有效编程:
class Example {
function Example()
{
}
function complexFunction():void
{
Car newCar = new Car("KK-E8", Color.Red, true);
carManager.Add(newCar);
User newUser = new User("Moritz", "Krohn", Country.Germany, true);
userManager.Add(newUser);
newUser.addCar(newCar);
...
}
有些课程往往会变得很大,即使你试图让事情井井有条。这绝不是一件坏事,也不是长期的功能。只是尝试将事物分开,尽量不要重复代码(为此创建函数)并尝试在单独的类中保持与彼此相关的事物。
答案 1 :(得分:0)
我个人发现,如果将复杂代码拆分为简单函数,它会增加复杂代码的可读性。 我在代码中没有真正得到的是将这些更简单的函数组合成一个函数的方式,这似乎只适用于根本不返回任何内容的函数(它们似乎只有一些效果)。从简单的函数构建复杂函数的一种更自然的方式是通过函数组合,区分或类似的东西......
答案 2 :(得分:0)
仅仅因为函数“长”并不会使它变得更复杂,有些东西只需要多行代码 举个例子:
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
loader.contentLoaderInfo.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
loader.contentLoaderInfo.addEventListener(Event.INIT, initHandler);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
loader.contentLoaderInfo.addEventListener(Event.OPEN, openHandler);
loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
loader.contentLoaderInfo.addEventListener(Event.UNLOAD, unLoadHandler);
loader.contentLoaderInfo.addEventListener(MouseEvent.CLICK, clickHandler);
var request:URLRequest = new URLRequest(url);
loader.load(request);
是“长”吗?是
它是否具有较高的Cyclomatic Complexity?没有
你可以清楚地了解这里发生了什么,并且很容易理解
你会发现具有低CC值的功能/方法总是更容易阅读
另一方面,具有高(+20)CC值的方法应该是一个红旗
将方法拆分为单独的辅助方法并不能解决手头的问题,实际上会使编译器变得更糟,因为现在它必须分配专用于那些只会被调用一次的方法的资源。
经验法则是避免超过CC值20
当你达到20以上时,是时候开始重新思考你的班级设计,因为它正在变得紧密耦合。
也许您应该问的问题是。
How can I reduce the Cyclomatic Complexity of this?