Java接口使用指南——接口中的getter和setter是坏的吗?

Java接口使用指南——接口中的getter和setter是坏的吗?,java,interface,javabeans,setter,getter,Java,Interface,Javabeans,Setter,Getter,人们认为在界面中使用的最佳准则是什么?什么应该和不应该进入接口 我听人说过,作为一般规则,接口只能定义行为而不能定义状态。这是否意味着接口不应该包含getter和setter 我的意见是:对于setter可能不是这样,但有时我认为getter可以有效地放置在接口中。这仅仅是为了强制实现类来实现这些getter,从而表明客户端能够调用这些getter来检查某些东西,例如。我不明白为什么接口不能定义getter和setter。例如,List.size()。接口必须定义行为,而不是实现——它不能说您将

人们认为在界面中使用的最佳准则是什么?什么应该和不应该进入接口

我听人说过,作为一般规则,接口只能定义行为而不能定义状态。这是否意味着接口不应该包含getter和setter


我的意见是:对于setter可能不是这样,但有时我认为getter可以有效地放置在接口中。这仅仅是为了强制实现类来实现这些getter,从而表明客户端能够调用这些getter来检查某些东西,例如。

我不明白为什么接口不能定义getter和setter。例如,
List.size()。接口必须定义行为,而不是实现——它不能说您将如何处理状态,但它可以坚持您可以获取并设置状态

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

编辑:注释表明getter和setter意味着一个简单的字段用于备份存储。我强烈反对这种暗示。在我看来,这意味着获取/设置值“相当便宜”,但并不是说它存储为一个带有一个简单实现的字段


编辑:如评论中所述,第7.1节中明确了这一点:

因此,即使脚本编写器键入 在诸如
b.Label=foo
仍有一个方法调用到 要设置属性的目标对象,以及 目标对象已满 程序控制

所以属性不需要简单 数据字段,它们实际上可以是 计算值。更新可能有 各种程序性副作用。对于 例如,更改bean的背景 颜色属性也可能导致 要用新的 颜色。”


如果假定的蕴涵是真的,我们可以直接公开属性和字段。幸运的是,这种蕴涵并不成立:getter和setter完全有权进行计算

例如,考虑一个带有

的组件
getWidth()
getHeight()
getSize()
你认为这意味着有三个变量吗?这两个变量中的任何一个都不合理:

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
}
或者(最好是国际海事组织):


这里的size属性或height/width属性只是为了方便起见,但我不认为这会使它们在任何方面无效。

我认为bean一般不应该在上面有一个接口。javabean是更一般意义上的接口。接口指定了更复杂的外部契约javabean的外部契约和内部表示是相同的


不过,我不会说接口中不应该有getter。拥有一个由DataThingieBean实现的可读DataThingie接口是非常有意义的。

进一步阅读:Java框架架构师的实用API设计自白(Jaroslav Tulach,2008,Apress).

这涉及到整个Getter/Setter都是邪恶的话题,在本网站和其他地方被多次提及


我倾向于在接口中不使用访问器,而是使用构造函数参数向实现中添加协作器。

事实上,直接实现某个对象是作为getter的,如果需要的话,它不应该停止在接口中。

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

  • 服务描述。这可能类似于
    CalculationService
    。我认为方法
    getX
    不应该出现在这种接口中,当然也不应该出现在
    setX
    中。它们非常清楚地暗示了实现细节,而这不是此类接口的工作
  • 数据模型的存在仅仅是为了抽象出系统中数据对象的实现。这些模型可能用于帮助测试,或者仅仅是因为像我这样年纪的一些人还记得(例如)使用持久性框架将您束缚在拥有特定超类的日子(也就是说,如果您切换了持久层,您可以选择实现一个接口)。我认为在这种类型的接口中使用JavaBean方法是完全合理的

  • 注意:collections类可能适合键入#2

    getter/setter本身并没有什么坏处。但是:

  • 我倾向于使我的对象相对于它们包含的字段是不可变的(在第一个实例中)。为什么?我在构建阶段实例化了大多数内容。如果我以后想更改某些内容,那么我会放宽这些限制。因此,我的接口将倾向于包含getter,而不是setter(还有其他好处——特别是线程)
  • 我希望我的对象为我做事情,而不是相反。因此,当我的一个对象获取了多个getter时,我开始询问该对象是否应该具有更多功能,而不是公开其所有数据以供其他对象使用。有关更多详细信息,请参阅

  • 注意,这些都是指导原则。

    我使用了这些类型的接口,例如,我们的类有字段beginDate和endDate。这些字段在许多类中,我有一个用例,我需要获取不同对象的日期,所以我提取了接口,非常高兴:)

    基本上如果我是否需要知道[state,property,whateverThignAMaGit]的值才能使用它的实例?“那么是的……访问器属于接口


    上面John的List.size()是一个需要在接口中定义的getter的完美示例

    getter用于查询对象的状态-在设计
    private Size size;
    
    public int getWidth() {
        return size.getWidth();
    }
    
    public int getHeight() {
        return size.getHeight();
    }
    
    public Size getSize() {
        return size;
    }