2011-09-05 49 views

回答

8

通行证中的属性值,以减少耦合是补间你的课。在这种情况下,定义GetNum的类不需要知道关于ClassA

最好减少类之间的耦合\依赖关系,因为这会使设计更加灵活。在你为方法提供复杂类型的地方,然后提供接口,以便你可以改变你传递的特定实现。这又使您的设计更灵活,更易于测试。

+1

+1,虽然这取决于。有一个名为[Introduce Parameter Object]的重构(http://www.refactoring.com/catalog/introduceParameterObject.html)。如果你有很多参数并且它们在逻辑上是相关的,那么创建一个小的[数据传输对象](http://en.wikipedia.org/wiki/Data_transfer_object)(从没有行为的意义上讲)可能是合理的。 – TrueWill

+1

@TrueWill:我不认为一定有什么矛盾说chibacity不过。我认为这只是一个有用的附加说明。这个数据传输对象毕竟不会与ClassA相关,它真的是由ClassA填充的GetNum,所以GetNum对ClassA仍然一无所知。 – Chris

+1

@Chris:我同意,因此+1。 :)但是有多种方法可以实现松耦合。例如,您可以应用[保留整个对象](http://www.refactoring.com/catalog/preserveWholeObject.html),但在参数类型上引入一个接口。在许多情况下,这是过度的,传递一个或两个属性值是最好的方法。如果你必须通过四个或更多的参数,它可能会变得混乱。 – TrueWill

1

我遵循的一般规则是这样的。该方法是否需要该对象?还是需要该对象的属性值?后者使得该方法更加可用(因为它不需要用户创建具有这些属性的任何类型的实例)。

你可以做什么,是提供过载(从而同时支持):

int GetNum(int x, int y) { return (x + y); } 
int GetNum(ClassA obj) { return GetNum(obj.X, obj.Y); } 

问问自己,什么是可能的用例的方法,然后问,如果你确实需要,需要传递一个包装值的实例。

考虑到我可能有以下方法:

public void ProcessMessage(Result result) 
{ 
    // Do something with Result.ReturnedMessage 
    result.ReturnedMessage.Process(result.Target); 
} 

它接受理论Result类型的单个实例,但现实是,它仅使用两个参数,所以我们可以重新定义为:

public void ProcessMessage(Message message, Target target) 
{ 
    message.Process(target); 
} 

这使得现在可以使用的方法可能更多的场景,当然,你可以定义过载,从ProcessMessage(Result)ProcessMessage(Message, Target)只是路线等

在另一方面,如果该方法形成的接口定义的一部分:

void ProcessMessage(Result result); 

你不能保证一个类型实施该方法不会要求获得更多的不仅仅是ReturnedMessageTarget性质。

底线是,考虑你的用例,以及它如何适应更大的设计。还要考虑未来的发展......如何使我们的理论型号Result变得容易?作为一个脚注,这是一个非常类似的论点,关于在哪里使用专用类型或基本类型来传递值。:

public void DoSomething(List<string> items); 
public void DoSomething(IList<string> items); 
public void DoSomething(IEnumerable<string> items); 

在上面的例子中,是你的方法做任何事情,明确要求List<string>类型,还是会与IList<string>接口定义工作...或者,如果你不是在所有添加任何..怎么样改为接受IEnumerable<string>实例。专业化方法调用越少,可以使用的方法越广泛。

1

我认为这在很大程度上取决于你自己的编码风格。

在我看来,如果该方法的目的是链接到该对象的方法应采取一个对象作为参数。例如,将对象的字段格式化为漂亮的文本字符串的方法应该将对象作为其参数。

在您的例子,该方法是不是真的与对象相关的 - 它可以采取任何两个数字,他们没有特定对象的工作被包裹起来,所以我觉得方法应该采取性质作为论据。

我不认为这会让你选择哪一种风格有很大的不同,虽然。

0

在这种情况下chibacity说GetNum并不需要了解ClassA的。但是,您可能会考虑实际添加GetNum作为调用GetNum传递适当值的ClassA的方法。它不一定写,但如果你打算做很多,这可能是有道理的。

0

我认为,像任何事物一样有趣,答案是“这取决于”。

的例子可能被简化太多,给予足够的情况下适当地回答这个问题。似乎有三种解决方法:1)int GetNum(ClassA myObject){}
2)int ClassA.GetNum(){}
3)int GetNum(int a,int b){}

在过去,我会赞成选项2的回落,使得GetNum ClassA的成员。 GetNum如何工作,或者从何处获取信息(调用者)只是想从ClassA对象获取数字,这与调用者的业务无关。选项代码需要知道ClassA的内容,所以这是不恰当的,即使它只使用两个getter。如果我们更了解上下文,那么也许选择一个会更好。我无法从这个问题中看出来。

有改善的代码工作中的可测性,特别是遗留代码巨大的利益。除非已经有了一个有用的单元测试框架,否则选项1和2需要ClassA的一个对象,被实例化用于测试。为了使代码可测试(特别是如果ClassA是昂贵的或不实际的实例化),我们一直在使用类似选项3的东西(或使其成为ClassA的静态成员)。这样,您不需要实例化或传递难以制作的对象,并且您可以轻松添加完整的代码测试覆盖率。

与往常一样,YMMV。

相关问题