Java接口使用指南 - 接口中的getter和setter是不是很糟糕?

His*_*His 35 java getter setter interface javabeans

人们如何看待在界面中使用的最佳指南?什么应该和不应该进入界面?

我听说有人说,作为一般规则,接口必须只定义行为而不是状态.这是否意味着接口不应包含getter和setter?

我的观点:对于制定者来说可能不是这样,但有时我认为吸气剂可以放在界面中.这仅仅是为了强制实现类来实现那些getter,以便表明客户端能够调用那些getter来检查某些东西,例如.

Jon*_*eet 24

我不明白为什么界面不能定义getter和setter.例如,List.size()实际上是一个吸气剂.接口必须定义行为而不是实现 - 它不能说你将如何处理状态,但它可以坚持你可以得到它并设置它.

例如,集合接口都是关于状态的 - 但是不同的集合可以以完全不同的方式存储该状态.

编辑:评论表明,getter和setter意味着一个简单的字段用于支持存储.我强烈反对这种含义.在我看来,有一个含义是获取/设置值"相当便宜",但并不是说它存储为具有简单实现的字段.


编辑:正如评论中所述,这在JavaBeans规范第7.1节中已明确说明:

因此,即使脚本编写器输入某些内容,例如b.Label = foo 仍然有一个方法调用到目标对象来设置属性,并且目标对象具有完全的编程控制.

因此,属性不仅仅是简单的数据字段,它们实际上可以是计算值.更新可能有各种程序性副作用.例如,更改bean的背景颜色属性也可能导致使用新颜色重新绘制bean."


如果假定的含义正确的,我们也可以直接将属性作为字段公开.幸运的是,这种含义并不成立:获取者和制定者完全有权计算事物.

例如,考虑一个组件

getWidth()
getHeight()
getSize()
Run Code Online (Sandbox Code Playgroud)

你是否相信存在三个变量?要么有以下方面是不合理的:

private int width;
private int height;

public int getWidth() {
    return width;
}

public int getHeight() {
    return height;
}

public Size getSize() {
    return new Size(width, height); // Assuming an immutable Size type
}
Run Code Online (Sandbox Code Playgroud)

或者(最好是IMO):

private Size size;

public int getWidth() {
    return size.getWidth();
}

public int getHeight() {
    return size.getHeight();
}

public Size getSize() {
    return size;
}
Run Code Online (Sandbox Code Playgroud)

这里size属性或高度/宽度属性只是为了方便 - 但我没有看到这使它们以任何方式无效.

  • 我不同意这个含义.如果想要,吸气者完全有权计算价值. (15认同)
  • 鉴于Java API充满了各种各样的东西,并且有充分的理由,我会说它正在做出这样的假设.我会说**暗示**是因为你正在调用一个方法而不是直接访问一个字段,你*不应该*假设它什么都不做.如果我真的想要传达只有一个要访问的字段,我将公开一个字段. (4认同)
  • "持久状态的一部分"!="该类型的字段".持久状态可以保存在地图中,也可以作为某种较大类型的一部分(如我所示的宽度/高度/大小示例). (3认同)
  • (否则你可能只是公开字段并完成它...使它成为一种方法的全部意义是*隐藏*实现.) (2认同)
  • 如果你假设getWhatever()只返回字段'what'的值,那么有一天(很快)某事会证明你错了 (2认同)

oxb*_*kes 13

我认为通常声明有两种类型的接口:

  1. 一个服务描述.这可能是这样的CalculationService.我不认为方法getX应该在这种界面中,当然也不应该setX.它们非常清楚地暗示了实现细节,这不是这种类型接口的工作.
  2. 一个数据模型 -只存在于抽象出来的数据对象的系统实施.这些可能用于帮助测试,或者仅仅因为像我这样的一些人记得(例如)使用持久性框架将你绑定到具有特定超类的日子(即,如果你切换,你会选择实现接口)你的持久层).我认为在这种类型的接口中使用JavaBean方法是完全合理的.

注意:集合类可能适合类型#2

  • 在您的上述场景中,您不需要图书管理员吗? (4认同)
  • 哈哈,是的.这正是我所需要的 - 一些中央*经理*的逻辑,而不是数据! (4认同)
  • 大概你的意思是我将数据与行为分开.它可能是老式的,但自从我10年前在这个"生动的对象社区"风格中在Smalltalk中编写了一个"库"程序以来,我唯一记得的就是我永远无法回想起我的业务逻辑所处的位置.书籍是否向客户贷款?或者客户检查了书籍? (3认同)

Bri*_*new 10

对于吸气者/制定者来说,没有什么本质上的邪恶.然而:

  1. 我倾向于使我的对象相对于它们包含的字段是不可变的(在第一个实例中).为什么?我在构建阶段实例化大多数事情.如果我想稍后改变一些东西,那么我放松这些限制.所以我的界面往往包含getter,但不包含setter(还有其他好处 - 特别是线程).
  2. 我希望我的物体为我做事,而不是相反.因此,当我的一个对象获得了许多getter时,我开始询问该对象是否应该具有更多功能,而不是将其所有数据暴露给其他可以使用的数据.有关详细信息,请参阅此答案.

这些都是指导方针,请注意.


Kev*_*son 6

一般来说,我认为 bean 上不应该有一个接口。javabean 是更一般意义上的接口。接口指定了更复杂的东西的外部契约。javabean 的外部契约及其内部表示是相同的。

不过,我不会说你不应该在接口中使用 getter。拥有一个由 DataThingieBean 实现的 ReadableDataThingie 接口是非常有意义的。