2011-09-07 100 views
5

我遇到了这个代码,其中一个方法调用,例如ClassA.search(a,b,flag)正在被3个控制器使用。这是该方法的简化版本:这是重用/共享方法的好方法吗?

public List<Result> search(Object a, Object b, boolean flag) { 
    //do some code logic here, common to the 3 controllers 
    //at the middle there is: 
    if (flag) { 
     //code that affects 2 Controllers 
    } else { 
     //code affects only 1 
    } 
    //some more common code 
    //some more code with the flag if else 
} 

这是一个好主意,因为代码被重用?还是有更好的方法仍然能够重用代码,但不会引入方法调用者(客户端)代码自定义的这个标志(例如可能将其分割为3种不同的方法,但仍然能够声明通用代码重构方法)?

回答

6

首先,提取与评论功能线:

public void search(Object a, Object b, boolean flag) 
{ 
    commonToThree(); 
    if (flag) 
    { 
     affectTwoControllers(); 
    } 
    else 
    { 
     affectsOnlyOne(); 
    } 
    alsoCommon(); 
} 

现在摆脱flag布尔的说法,这是一个代码味道:

public void searchWithTrueFlag(Object a, Object b) { 
    commonToThree(); 
    affectTwoControllers(); 
    alsoCommon(); 
} 

public void searchWithFalseFlag(Object a, Object b) { 
    commonToThree(); 
    affectsOnlyOne(); 
    alsoCommon(); 
} 
+0

我同意这一点,只要你不把局部变量变成字段来使它工作。 –

+0

为什么你会发现局部变量不好?如果您必须反复遍历参数的状态非常重要,请创建一次性对象,并将状态初始化为构造函数中的最终字段并仅使用一次。功能类固醇;-)。 –

+0

这是真的,但添加一个类与字段(和一个构造函数?)是很多工作,以避免一个标志。 ;) –

3

这很好但不是很好。一个布尔值是有道理的,但如果你开始添加更多的布尔值,那么你不会进入正确的方向。

这并不总是可能的,但通常能产生更好的代码做:

functionOne: 
    sharedCodeOne() 
    specificCode 
    sharedCodeTwo() 

functionTwo: 
    sharedCodeOne() 
    specificCode 
    sharedCodeTwo() 

一如往常,这是很难做出广义声称:这显然并不总是可能/实用。

+1

+1:如果代码的三个部分不共享任何局部变量,这很好。(或者只是分享一小部分) –

+1

@彼得:我完全同意 - 我认为这种方法的实际和优势在于它促使您减少局部变量的数量和范围。 (虽然有些人可能倾向于把他们变成封闭类的领域,使事情变得糟糕) –

+1

@Arnout Engelen,我同意添加字段来完成这项工作并不是一个好主意。 –

0

这是一个相对简单的方法来做到这一点。有替代品,但它们可能更加复杂。 (例如传递访问者或调用控制器的方法来说明对该控制器做什么)

如果您在代码的三个部分之间共享局部变量并且您将不得不使用字段,那么此方法是最好的。

0

我会采取不同的方式试图回答这个问题一般来说:

主要目标应该是干净代码。究竟是什么,当然取决于具体情况。但是可以肯定的是,在多个地方使用复制粘贴的代码是不好的,因为如果必须进行更改,这需要更改几个位置 - 而且,尝试提取公共部分是不好的,因为不止一个部分正在使用他们在任何情况下。

总是想象有人必须阅读你的代码(或者你自己必须从现在开始几周内完成),并且尽可能快地理解那里发生了什么。所以,这取决于特殊情况,如果最好复制一些行或用一种常用方法提取它们。

一个标志本身并不坏,但它并不是真正应该在java方法中过度使用的东西。通常情况下,这种情况可以通过重载方法并在另一方中使用一种方法来很好地解决,因此常见情况是在一个情况下完成的,而在另一个情况下是特殊情况。或者,您可以有几个子方法,并通过多次调用来编写您的方法,但只有在您不需要传递太多参数时才有意义。

一个规则(完全是主观的,但基于从许多项目中吸取的教训)我可以给你:喜欢具体的实现ober通用方法。它们可能导致更多的代码,并且可能看起来不太聪明,但它们更容易理解,扩展和调试。