代码之家  ›  专栏  ›  技术社区  ›  Gnoupi

在爪哇,对于复杂模型使用接口有性能上的提高吗?

  •  4
  • Gnoupi  · 技术社区  · 14 年前

    标题很难理解,但我不知道如何用另一种方式来概括。欢迎编辑澄清。

    有人告诉我,并建议我使用接口来提高性能,即使在不需要特别需要常规的“接口”角色的情况下。在这种情况下,对象是大型模型(MVC的意思是),有许多方法和字段。

    向我推荐的“良好使用”是创建一个具有其独特实现的接口。当然,不会有任何其他类实现这个接口。我被告知这样做更好,因为它“向将使用此类方法的其他类“公开较少”(或接近的内容),因为这些对象是从其接口引用对象(实现中的所有公共方法都在接口中复制)。

    这对我来说似乎很奇怪,因为它对我来说就像是C++(带有头文件)。我明白了这一点,但在Java中呢?

    为这种独特的实现设计一个接口真的有意义吗?我非常感谢对这个话题的澄清,所以我可以证明 遵循这种行为,以及复制所有声明所带来的麻烦。


    编辑: 感谢所有人的回答,这真的很有帮助和指导意义(他们中的大多数,不仅是“接受”的一个)。

    显然在性能上没有优势,除了界面通常的OO角色之外,我现在有了更大的兴趣范围(取决于具体情况)。

    10 回复  |  直到 14 年前
        1
  •  12
  •   Péter Török    14 年前

    使用接口与性能关系不大(除了开发团队的性能,即开发速度)。它更多的是控制依赖关系,并分离程序的不相关部分。

    如果您的代码直接依赖于具体的C类,那么该代码就更难进行单元测试。如果您依赖于一个接口,那么在单元测试中创建一个模拟实现就很容易了。

    当然,你 可能不需要全班的方法 进入父接口。事实上,你 可能不需要一个单独的父接口 . 分析该类的使用情况,并且(尤其是像您这样的大类)可能会发现两个或更多不同的方法组,由不同的客户机使用(例如,一组客户机只查询对象状态,而另一组客户机则更新对象状态)。这使得创建两个或多个不同的接口成为可能,每个接口都更简单、更清晰。

    这种分析甚至可能得出这样的结论:你的班级正在尝试做太多的事情(而不是 single responsibility ,您最好将它的一些内容提取到单独的类中!换句话说,一旦你开始考虑接口和编程,你就开始在不同的层次上看到设计,这可能会导致更好的设计解决方案。

    所有这些都说明了,如果在上面所有的分析之后,您仍然发现模型类的接口没有任何用处,那么就记下它。比如说,半年后再看一次。然后, 如果你仍然觉得它没有自己付钱,就把它扔掉吧。 . 接口——就像程序的任何其他元素一样——应该总是 有明确的目标和存在的理由 (比“我的同事让我创造它”更好的一个)。它们不是万能药。如果你聪明地使用它们,你就可以使你的代码更好。如果你愚蠢地使用它们,你的代码会变得更糟。你在这里发布这个问题的事实意味着你想学习如何巧妙地使用它们,这是很好的:—)

        2
  •  4
  •   Uri    14 年前

    首先,接口没有任何性能优势。如果有的话,使用多态代码和动态调度(如C++虚拟函数)会带来成本。

    不要把界面看作是增加表达能力的东西,而要把它看作是限制你更好地写作的东西。接口很重要,imho,有三个原因:

    1) 可以 帮助您编写具有更好封装、数据隐藏、稳定性等功能的代码。

    2) 可以 通过思考您试图表示的内容而不是如何实现,帮助您分离行为和实现。不能添加状态对于防止意外添加状态有很大作用。

    3)它们允许您在将来扩展内容,并将代码分成独立的单元。每个组件只知道它需要知道的关于其他服务的信息。

    您可以使用没有状态的抽象类来完成其中的一些操作,但是接口是专门为此设计的,并且具有多个子类型的好处。在C++中,这样的抽象类经常被用来模拟接口。

    现在,如果您可以用类直接编写具有完美封装级别的大型系统,那就太好了。但对于阶级来说,常常有一种诱惑,即过早地引入国家并建立联系。

    你应该总是写接口吗?当然不是。总是害怕“总是”的规则:)它总是在浪费的工作和无用的复杂性和好处之间取得平衡。有了时间和经验,你就有了直觉。

    此外,头文件本质上是接口文件。它们通常定义允许的行为,但没有状态。如果你学习C,然后学习Java(一些学校这样做),你将学习C中的ADTs,然后使用接口来了解Java中的ADTS。

        3
  •  4
  •   Brian Agnew    14 年前

    简要

    1. 您正在接口对象中显式记录该模块的API。它对您的用户来说会更清楚,也许会让您考虑该界面中的内容。
    2. 您可以在同一对象上提供多个接口,并限制使用者的功能(例如只读与读写)
    3. 模拟框架利用接口,模拟类是一种非常强大的测试技术
        4
  •  3
  •   Riduidel    14 年前

    事实上,使用接口而不是类可以实现以下三点:

    1. 将契约从其实现中区分出来:契约是接口(这是您声明要做的),类显然是实现
    2. 提供易于替代的实现。这方面的典型例子意味着在不修改用户代码的情况下用另一个存储机制替换存储机制(例如,通过项目voldemort重新封装mysql)
    3. 作为2的一个好处(这一次很容易扩展到模型元素),接口允许您进行某种白盒测试:通过使用模拟框架(jmock、easymock,……),您将通过一个所谓的“mock”返回您对测试的期望值,重新计算接口的实现,这可能是可疑的行为。这将允许您的测试不仅检查一个组件,而且确保错误来自该组件,而不是来自其内部承包商(您提供给他的接口)。
        5
  •  2
  •   Dr. Hans-Peter Störr    14 年前

    使用接口的这个原因对我来说也很奇怪。我不知道怎么会有任何性能优势,如果有,可能完全不重要。

    也就是说,即使目前有一个实现,也有一些理由使用接口。稍后扩展或提供替代实现可能更容易。(尽管在任何一个合适的IDE中都有一个提取接口重构。)测试可能要容易得多:如果您想测试一个只通过接口使用其他类的类,那么您可以很容易地为其他类提供模拟对象。

        6
  •  2
  •   Anonym    14 年前

    下面有两个链接可以解释您为什么要这样做:

    http://www.artima.com/lejava/articles/designprinciples.html http://pragmaticjava.blogspot.com/2008/08/program-to-interface-not-implementation.html

    它与执行性能无关(更多的是与程序员(您)的性能有关),因为您正在将类的用户从其实现中剥离出来,以及其他一些减轻可测试性和可维护性的事情。

    当然,不会有任何其他类实现这个接口。

    也许今年不会,但明年可能会。

        7
  •  1
  •   Adam Gent    14 年前

    接口在Java中被过度使用,部分原因是语言设计,部分原因是人们认为大量接口是好的设计。

    如果Java允许多重继承,抽象类将优于接口。scala是一种新的JVM编程语言,它有一个特性概念,本质上是具有mi功能的抽象类。

    抽象类的优点是,您可以向抽象类添加行为,而不必破坏扩展它的现有类。因此,抽象类作为扩展机制(插件)比接口更好。

    不幸的是,jmock和它的兄弟们鼓励为BDD测试提供许多接口,但这并不一定是真的,因为至少有两个库来模拟具体的对象。

        8
  •  0
  •   Community Egal    7 年前

    This question targeted C# 但我认为这也适用。最高投票的答案是为每个类定义一个接口 只是代码噪音 .

        9
  •  0
  •   Michael Borgwardt    14 年前

    有一个相对常见的开发原则,即几乎所有东西都应该有一个接口。据我所知,这要么基于一种对“程序到接口,而不是实现”的“货物崇拜”思想(这绝对不要求你到处乱扔接口代码),要么基于使用旧的模拟框架进行测试驱动的开发,而旧的模拟框架不能模拟具体的类。

    不要理会这种胡说八道。

        10
  •  0
  •   ring bearer    14 年前

    还有另一种滥用接口的方法?

    使用接口没有明显的性能提升。 相反,它 可以 由于rtti(基于编译器的特性),会对性能产生负面影响。