V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bigbigeggs
V2EX  ›  Java

大家怎么看待 effective Java 接口只用于定义类型 这一个准则。

  •  
  •   bigbigeggs · 2020-04-07 20:53:04 +08:00 · 4213 次点击
    这是一个创建于 1690 天前的主题,其中的信息可能已经有所发展或是发生改变。
    • 这条认为在接口中定义常量是错误的,不规范的

    • 应该用类来定义常量

    • 感觉基本上项目中常量都是写在接口上面吧

    • 各位老哥怎么看?

    26 条回复    2020-06-28 16:37:20 +08:00
    Honwhy
        1
    Honwhy  
       2020-04-07 21:40:26 +08:00
    不知道这条规则是不是要表达这个意思

    ```java
    public interface Intf {
    public final static String CONSTANT = "1";

    public static class IntfImpl implements Intf {
    public final static String CONSTANT = "2";
    }
    public static final class StaticClazz {
    public final static String CONSTANT = "3";
    }
    public static void main(String[] args) {
    System.out.println(Intf.CONSTANT);
    System.out.println(IntfImpl.CONSTANT);
    System.out.println(StaticClazz.CONSTANT);
    }
    }

    ```
    sakura1
        2
    sakura1  
       2020-04-07 21:46:12 +08:00
    看到 effective java 就来了,虽然目前主写 scala,mark 一下
    majiaxin110
        3
    majiaxin110  
       2020-04-07 22:41:25 +08:00
    > 基本上项目中常量都是写在接口上面吧

    求例子,我目前还真没见过接口有很多常量的
    Xbluer
        4
    Xbluer  
       2020-04-07 23:13:08 +08:00
    Interface/接口 就是用来定义具有若干个方法的功能集合,描述实现接口的类 class 需要实现的功能。如果接口中包含了常量,那么这些常量就涉及到了实现相关的细节,职责不清。

    也有历史遗留项目中会专门建立一些接口,里面仅仅包含常量。个人认为这么用勉强也行。

    定义常量量更好的方式是定义 enum,或者 class 中 public stat final xxx.
    chanchan
        5
    chanchan  
       2020-04-07 23:34:30 +08:00
    接口装常量?我从不这么做,我也不知道为什么...
    collery
        6
    collery  
       2020-04-07 23:38:22 +08:00
    @chanchan 哈哈 我之前公司有个同事喜欢 接口里面写常量
    charlie21
        7
    charlie21  
       2020-04-07 23:40:18 +08:00
    轻型接口不需要

    重型接口随便
    SaulLawliet
        8
    SaulLawliet  
       2020-04-07 23:43:06 +08:00
    常量写在接口上比较省事. 有时一两个常量, 懒得专门定义一个工具类.
    我觉得实际要看常量的数量把, 少了就写在接口上, 多了就定义一个工具类用来导出常量,
    lee015
        9
    lee015  
       2020-04-08 01:34:41 +08:00 via Android
    不会单独写个接口放常量。如果是接口方法参数用到少数几个常量可选取值,会放这个接口里一起写。
    SoloCompany
        10
    SoloCompany  
       2020-04-08 02:13:21 +08:00
    你应该是理解错了
    并不是不建议在接口上定义常量
    而是接口不应该只用来定义常量

    以及比如利用 "实现" 接口来 "继承" 常量是一个 bad pratice
    相对而言更正确的做法应该是使用 static import

    > The constant interface pattern is a poor use of interfaces.
    xcstream
        11
    xcstream  
       2020-04-08 04:02:52 +08:00
    代码量越多看上去越复杂 kpi 就多
    wysnylc
        12
    wysnylc  
       2020-04-08 10:10:29 +08:00
    时代在发展,接口已经可以写 default 了,让作者更新下书吧
    YzSama
        13
    YzSama  
       2020-04-08 10:12:42 +08:00
    其实,如果是 SDK 接口。可以这么直接定义
    有些开源项目,定义好某些模块的功能接口 会直接把 请求地址写在 interface 类上 。实现的时候,直接使用定义好的地址。

    本来 接口上定义的 变量,就是 常量。
    hantsy
        14
    hantsy  
       2020-04-08 11:56:49 +08:00
    @wysnylc 有最新版本,更新到 9,11 了吧。
    hantsy
        15
    hantsy  
       2020-04-08 11:59:46 +08:00
    接口定义常量,只能说明你的程序可以执行。合理与否,看这个接口本身的设计目的,是不是为了其实现类中使用。如果纯粹是用接口来定义常量,只能说有毛病。
    yidinghe
        16
    yidinghe  
       2020-04-08 12:44:23 +08:00
    当 java 发展到 5.0,出现枚举类型后,不论是在接口还是在类中定义常量,都已经不是设计的首选。尤其是通过接口来定义常量。如果用类来定义的话,起码还能将常量类型定义为这个类自身,起到类似枚举的效果;而接口就做不到了。
    brucewuio
        17
    brucewuio  
       2020-04-08 14:04:11 +08:00
    没有什么教条,看实际情况,吸收具体情况所需要的知识
    wozhizui
        18
    wozhizui  
       2020-04-08 15:06:37 +08:00
    接口主要定义抽象方法吧,针对接口编程,主要是 implement 后,实现相应的方法。
    常量理解成属性,接口针对的是方法,属性一般不应该写在接口中吧,我是这么理解的。
    bigbigeggs
        19
    bigbigeggs  
    OP
       2020-04-08 21:24:01 +08:00
    @SoloCompany
    static import?
    那比如项目中大量的常量应该统一写在哪里比较合适呢?
    bigbigeggs
        20
    bigbigeggs  
    OP
       2020-04-08 21:25:32 +08:00
    @majiaxin110
    基本上每个公司的项目中,有统一存放常量的地方吧。
    我们的项目基本都在 xxxConstans 接口类中。
    不放接口,那应该放在那里?
    SoloCompany
        21
    SoloCompany  
       2020-04-08 22:00:50 +08:00
    @bigbigeggs #18 那句话的意思是说

    不要使用没有任何实际意义的接口
    比如 interface C { const X }, class A implements C { use(X) }

    如果还是希望使用毫无意义的常量容器, 应该写成类 (concret 或 abstract 都无所谓)
    比如 abstrace class C { const X }, import C.x; class A { use(X) }

    而如果 C 本身是有意义的, 并且 X 和 C 的定义(contract) 紧密关联, 则并没有什么不妥
    majiaxin110
        22
    majiaxin110  
       2020-04-08 22:49:42 +08:00
    @bigbigeggs 我认为应该考虑常量出现的场合分散放在合适的类里,尽可能使用枚举等,实在不行的话也是放在具体的类里而非接口。当然我觉得约定好了其实这个也没有大碍
    EastLord
        23
    EastLord  
       2020-04-09 16:06:27 +08:00
    我认为常量应该定义在类中而不是接口中
    BBCCBB
        24
    BBCCBB  
       2020-05-23 15:30:45 +08:00
    我就是定义在接口里的, 仅仅是不想写前面那坨 public static final 而已.

    这个规则根据个人实际情况来.
    BBCCBB
        25
    BBCCBB  
       2020-05-23 15:31:22 +08:00
    接口名后面加上 Constant, 这已经够明显了吧.
    shupaiqianbi
        26
    shupaiqianbi  
       2020-06-28 16:37:20 +08:00
    这条的前提是 只定义常量的接口被子类实现了。
    那么就有以下几种考虑:
    1. 如果此接口被子类实现有什么不妥?
    2. 如果没有子类去实现此接口,而是直接引用有什么不妥?

    回答:
    1. 如果被子类实现后,在以后扩展中为了二进制兼容性,不管以前使用的常量还有没有使用,此接口都需要一直实现。所以这种方式不妥。
    2. 如果是引用的方式使用接口中的常量或者类定义常量,其实都不如引用枚举类。及时不使用枚举类,在语义上接口更容易让人混淆,不如类来的清晰。毕竟大家看到接口的第一印象就是有类去实现。

    个人愚见,不认同的可以多多讨论。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1695 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 16:44 · PVG 00:44 · LAX 08:44 · JFK 11:44
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.