将包含对象作为参数传递给包含对象的方法(如下面的简化示例所示)是不是不好的设计?
class A
{
private B _containedObject;
public A(B b)
{
_containedObject = b;
//...
}
public void SomeMethod()
{
//...
_containedObject.SomeMethod(this);
//...
}
}
class B
{
public void SomeMethod(A a)
{
//do something with a
}
}
P.s.上面的例子只是为了说明包含关系以及将包含对象传递给被包含对象而进行简化,其本身并没有说明这样做的目的。不过请放心,这是有目的的。
最佳答案
有时您可能希望将包含对象作为参数传递给被包含对象。正如其他发帖者所指出的,这被称为“双重调度”。 Smalltalk 语言提供了一个典型的例子。
该示例是将整数和 float (或其他类型的数字)相加。在 C++ 或 Java 中,您的整数类将具有多态方法,例如:
Integer {
add(Float) {...}
add(Integer) {...}
add(UserDefinedType) {...}
}
每种add方法都可以实现不同类型的加法正确。编译器使用类型信息来选择正确的方法。语句 Integer(6).add(Float(1.0)) 将调用 Integer::add(Float) 方法。
与 C++ 和 Java 不同,Smalltalk 是动态类型的。一个 Smalltalk 类只能有一个名为 add 的方法。
整数::add(对象)
编译器不知道“object”的类。因此,Smalltalk 无法像 C++ 或 Java 那样实现add。相反,Smalltalk 使用双重调度。它的工作原理如下:
Integer {
add(Object o) {
return o.addToInteger(this)
}
}
其他数字类,如 Float、Fraction 甚至 Integer 都实现了 addToInteger() 方法。
Float {
addToInteger(Object o) {
//Perform float + in math
return result
}
}
双分派(dispatch)解决了如何在动态类型语言中多态地实现man操作的问题。但还有一个更常见的用途:访问者模式。我会将其放在单独的答案中。
关于c# - 将包含对象作为参数传递给包含对象的方法是不是不好的设计?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8712850/