我们应该避免使用Object作为方法的输入参数/输出值吗?

时间:2010-05-19 12:13:18

标签: language-agnostic oop dependency-injection

以Java语法为例,尽管问题本身与语言无关。如果以下代码段在方法MyAbstractEmailTemplate中将对象setTemplate作为输入参数,则类MyGateway将与对象MyAbstractEmailTemplate紧密耦合,从而减少了对象类MyGateway的可用性。

折衷方案是使用依赖注入来简化MyAbstractEmailTemplate的实例化。这可能会解决耦合问题 在某种程度上,但界面仍然僵硬,几乎没有提供足够的灵活性 其他开发人员/应用程序。

因此,如果我们只使用原始数据类型(甚至是Web服务中的普通XML)作为方法的输入/输出,似乎耦合问题不再存在。所以你怎么看?

public class MyGateway {

    protected MyAbstractEmailTemplate template;

    public void setTemplate(MyAbstractEmailTemplate template) {
        this.template = template;
    }
}

6 个答案:

答案 0 :(得分:4)

很难理解你真正要问的是什么,但是将所有内容输入到Object 的路径并不会导致松散耦合,因为如果没有向下转换,你就无法对输入做任何事情,会打破Liskov Substituion Principle

走极端,它会引导你到这里:

public class MyClass
{
    public object Invoke(object obj);
}

这不是松散耦合,只是模糊且难以维护代码。

答案 1 :(得分:3)

名称MyAbstractEmailTemplate让我相信你在谈论一个抽象类。

你应该始终对接口进行编程,因此它不是依赖于MyGateway MyAbstractEmailTemplate,而是取决于EmailTemplate接口,其中{{1} }}。然后,您可以根据需要传递自定义实现,而无需进一步紧密耦合。

将它与DI相结合,你就得到了一个相当不错的解决方案。

不完全确定“界面仍然僵硬”是什么意思,但显然你应该设计你的界面,以便提供你需要的功能。

答案 2 :(得分:1)

MyGateway必须假设有关输入的某些内容。即使它使用XML,也必须假设XML的结构和内容。耦合本身并不是一种邪恶;表达两段代码之间的契约。经常重复的避免紧耦合的建议实际上只是说耦合应该表达契约的本质,而不是更多而不是更少。传递特定类型(特别是接口类型)是实现这种平衡的一种非常好的方法。

答案 3 :(得分:0)

恕我直言,使用对象(小帽,而不是Object s)作为方法参数和/或类成员没有任何内在错误。是的,这些创建了依赖项。您可以(至少)以两种方式管理:

  • 承认通过创建这种依赖关系,这两个类紧密耦合。这在许多情况下是完全合适的,其中两个(或更多)类实际上形成组件,这本身就是一个有意义的重用单元,其部分可能没有多大意义或可以互换。
  • 如果方法参数有多个可互换的候选项,则这些是构成类层次结构的明显候选者。然后你为接口编程并且可以将实现该接口的任何类的任何对象作为参数传递给你的方法。
    注意短语“有多个可互换的候选方法参数”Liskov Substitution Principle的松散改述,这是多态性的基础。
  • 在某些语言中,例如C ++,第三种方式是使用模板。然后,您不需要通用接口,只有特定的方法/成员在实例化模板时才需要解析。但是,由于实例化在编译时发生,因此这是完全静态绑定。

答案 4 :(得分:0)

您将遇到的第一个问题是很多类型根本无法通过原始数据类型表示(这是一个基本类型的Java问题。)。

应使用适当的继承层次结构来减少耦合。什么意思合适?该方法应该将接口的那一部分作为需要的参数。不多也不少。

毕竟你将无法避免依赖。方法必须知道他们可以对他们的输入做些什么,或者必须能够做出关于输入功能的假设(参见C ++概念)。

答案 5 :(得分:0)

问题是我会说,最好的java可以提供接口,人们开始看到它们太僵硬了。使用Go语言中的内容会很有趣,它允许灵活地检查接口的所有方法是否存在于类型中,您不必明确地实现某些接口。我们还需要比接口更好的东西来指定约束 - 可能是某种契约。另一件事是界面演变。