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

对 Java 泛型的顶级理解

  •  1
     
  •   mannixSuo · 2023-06-10 09:43:30 +08:00 · 6660 次点击
    这是一个创建于 530 天前的主题,其中的信息可能已经有所发展或是发生改变。
    public abstract class ServiceA<SEAL extends SealServerServiceAbst<F, FPR, FSUP, FGD, FFE, FSTP, FMBF>,
            F extends ApplyCommon<FPR, FSUP, FGD, FFE, FSTP, FMBF>,
            FPR extends ApplyPartnerCommon<FMBF>, 
            FSUP extends SubPlanCommon, FGD extends CmContGoodCommon,
            FFE extends  FileCommon,
            FSTP extends  StampCommon, 
            FMBF extends  FileCommon,
            V extends  ApplyCommon<VPR, VSUP, VGD, VFE, VSTP, VMBF>,
            VPR extends  ApplyPartnerCommon<VMBF>, 
            VSUP extends  SubPlanCommon, VGD extends  GoodCommon,
            VFE extends  FileCommon,
            VSTP extends  StampCommon, VMBF extends  FileCommon>
            extends ServiceB< Apply,  ApplyMapper>
            implements TopService<V, VPR, VSUP, VGD, VFE, VSTP, VMBF> {
            // 一些业务逻辑
            }
    
    

    前几天看到其他人写的一段代码,一眼给我看蒙了。 问了他才知道,因为和前端对接使用了 DTO ,FORM 两种参数类型,然后又和其他模块对接,又使用了一种参数类型。 他呢就把这几个参数抽象成泛型,在定义一个的抽象 service 如上,每种 service 处理不同类型的参数。 按我的理解,不管是前端交互还是给其他服务调用,就算参数不一样,一个 service 也能够进行处理啊。 他这个是不是过度设计了?

    66 条回复    2023-06-12 09:14:55 +08:00
    hidemyself
        1
    hidemyself  
       2023-06-10 09:46:50 +08:00   ❤️ 4
    这种代码,我可能看一眼就放弃了,写的什么玩意儿
    vitovan
        2
    vitovan  
       2023-06-10 09:52:01 +08:00   ❤️ 2
    @hidemyself #1 同意一楼,这代码如果不是生成的,而是手写的,那……只能甘拜下风望尘莫及五体投地顶礼膜拜以头抢地四仰八叉无话可说。
    optional
        3
    optional  
       2023-06-10 09:57:46 +08:00   ❤️ 2
    这就是典型的为了 DRY 而 DRY ,我愿称之为,好看的屎。
    tairan2006
        4
    tairan2006  
       2023-06-10 10:09:24 +08:00 via Android
    过度设计了
    totoro52
        5
    totoro52  
       2023-06-10 10:21:59 +08:00
    我甚至都不敢看完这代码,放弃,这要是改个参数 全炸
    DTCPSS
        6
    DTCPSS  
       2023-06-10 10:22:12 +08:00   ❤️ 4
    看那一排排泛型约束我还以为看汇编呢
    ns09005264
        7
    ns09005264  
       2023-06-10 10:22:54 +08:00   ❤️ 2
    我在 bevy 游戏引擎里看到过大量的泛型设计,如果把一层层的抽象拍平了,可能也没有这么多的泛型同时在一起。
    抽象设计烂才会同时出现这么多的泛型。
    jwenjian
        8
    jwenjian  
       2023-06-10 10:23:59 +08:00   ❤️ 6
    本来想进来学点知识的, 换个标题吧
    olaloong
        9
    olaloong  
       2023-06-10 10:30:14 +08:00
    恐怖如斯,一眼看下去看岔了方括号的边界,还纳闷这怎么继承了 2 个类...
    beneo
        10
    beneo  
       2023-06-10 10:36:13 +08:00
    这个问题其实主要取决于具体的项目需求和项目规模。使用泛型确实可以让代码更加通用和灵活,但同时也可能增加代码的复杂度。

    1. 在大型项目中,可能会有多种类型的参数,并且参数类型可能会频繁变化。这种情况下,使用泛型可以更好地解耦,使代码更加灵活,更易于维护。

    2. 泛型的使用也使得代码的重用性更强。你可以定义一个方法处理多种类型的参数,而不需要为每一种参数都编写一个特定的方法。

    3. 另一方面,过度的抽象可能会使代码更难理解和维护。太多的泛型可能会导致代码变得复杂和难以理解。同时,如果项目需求并不需要这么高的抽象级别,过度的设计可能会浪费开发和维护的时间。

    总的来说,这个设计可能并非过度设计,而是取决于具体的项目需求和项目规模。如果这个设计能够提高代码的重用性、灵活性和可维护性,那么这种设计是有价值的。但如果这个设计增加了代码的复杂性,而没有带来足够的好处,那么这可能就是过度设计了。
    yazinnnn
        11
    yazinnnn  
       2023-06-10 10:36:14 +08:00
    太蠢了, 这兄弟是不是不会写方法泛型?
    luzemin
        12
    luzemin  
       2023-06-10 10:36:42 +08:00
    这叫滥用,不叫设计
    PVXLL
        13
    PVXLL  
       2023-06-10 10:40:27 +08:00 via iPhone   ❤️ 8
    还以为是讨论为什么不能 new T(),结果是是来看屎山中的屎山
    nulIptr
        14
    nulIptr  
       2023-06-10 10:41:25 +08:00
    一个 service 可能最终依赖这么多 service ,但一般也是用啥就注入进来当作属性就行了,没必要放继承里面
    pursuer
        15
    pursuer  
       2023-06-10 10:45:50 +08:00
    虽然很长,但不复杂,只是必要性不高。类型体操还得看 typescript ,还有那些真的把模板用作元编程的 c++代码。。。
    wanguorui123
        16
    wanguorui123  
       2023-06-10 10:47:24 +08:00
    JAVA 的泛型就是假泛型底层全是转为 Object ,C#的泛型才是真泛型
    WIN2333
        17
    WIN2333  
       2023-06-10 11:04:01 +08:00
    写的跟狗屎一样,一段代码你两分钟内很难理解,那基本上都是段垃圾代码了,代码是写给人看的,不是写成这个狗屎样子的
    ghost024
        18
    ghost024  
       2023-06-10 11:05:24 +08:00
    我看了一下,其实很多泛型都是顶层抽象类的,我不理解的地方在于,为什么顶层的抽象类要写这么多的泛型,如果是需要在抽象类中定义抽象方法的返回参数就用 extends 的那些类型就好了,反正你的参数一定是这些类型或者这些类型的子类
    gowk
        19
    gowk  
       2023-06-10 11:06:57 +08:00 via iPhone
    完全没必要
    组合优于继承
    agagega
        20
    agagega  
       2023-06-10 11:07:57 +08:00   ❤️ 2
    这对 Java 来说已经离谱了,但对 C++而言可能才刚刚开始,是时候给 Java 程序员一点小小的模板震撼了
    auh
        21
    auh  
       2023-06-10 11:15:50 +08:00
    顶级的理解,只在他的脑子里面。这防离职代码写的好
    oaix
        22
    oaix  
       2023-06-10 11:27:00 +08:00
    只要我看不懂的代码:过度设计,只要看不懂我写的代码:辣鸡🐶
    iamzuoxinyu
        23
    iamzuoxinyu  
       2023-06-10 11:31:23 +08:00
    一股子 Rust 味儿
    iOCZ
        24
    iOCZ  
       2023-06-10 11:31:46 +08:00
    写代码要考虑读代码的人的心智负担
    NextWorld
        25
    NextWorld  
       2023-06-10 11:39:47 +08:00
    把 Java 泛型用成了 c++模板的样子了
    mannixSuo
        26
    mannixSuo  
    OP
       2023-06-10 11:50:54 +08:00
    @beneo 怎么一股子 chatGpt 的味道
    mannixSuo
        27
    mannixSuo  
    OP
       2023-06-10 11:52:48 +08:00
    @agagega C++如此离谱吗?但是把我感觉写代码是给人看的,要人能看得懂才行
    Slurp
        28
    Slurp  
       2023-06-10 11:53:33 +08:00
    闹麻了,扯 C++ Rust 都是看不懂的归于一类是吧?
    wolfie
        29
    wolfie  
       2023-06-10 12:00:13 +08:00   ❤️ 4
    纯傻吊设计

    不看需求,过度设计,限制一堆,
    未来需求变更 扩展麻烦。
    可读性差 别人没法接手不说,未来自己都有可能看不懂。
    xingda920813
        30
    xingda920813  
       2023-06-10 12:04:13 +08:00   ❤️ 2
    @wanguorui123 This is incorrect. 是擦除到第一个原始上界, <T extends Comparable<Number> & Serializable> 会被擦除为 Comparable (raw type), 而不是 Object.
    TWorldIsNButThis
        31
    TWorldIsNButThis  
       2023-06-10 12:37:29 +08:00 via iPhone
    名字缩写问题比较大

    其他没什么看不懂的 问题是要不要这么做

    java 泛型复杂不了,又不是 ts 能写逻辑
    6IbA2bj5ip3tK49j
        32
    6IbA2bj5ip3tK49j  
       2023-06-10 13:30:54 +08:00 via iPhone
    Java 业界最大的问题就是这种傻逼的抽象太多了。
    wanguorui123
        33
    wanguorui123  
       2023-06-10 13:43:43 +08:00
    @xingda920813
    Java 泛型的实现是靠类型擦除技术实现的,类型擦除是在编译期完成的,也就是在编译期,编译器会将泛型的类型参数都擦除成它指定的原始限定类型,如果没有指定的原始限定类型则擦除为 object 类型,之后在获取的时候再强制类型转换为对应的类型,因此生成的 Java 字节码中是不包含泛型中的类型信息的,即运行期间并没有泛型的任何信息。
    devilweime
        34
    devilweime  
       2023-06-10 13:52:42 +08:00
    功能没啥增加的话,为什么不写个转换,转成一种参数一个 service 处理
    Anarchy
        35
    Anarchy  
       2023-06-10 14:21:46 +08:00 via Android
    就不能多拆几个么,非得挤在一个类里么。这个不是过度设计而是懒得设计。
    otakustay
        36
    otakustay  
       2023-06-10 14:24:53 +08:00   ❤️ 1
    这在 TS 里不就是常规代码么 233
    zhuzhibin
        37
    zhuzhibin  
       2023-06-10 14:32:22 +08:00 via iPhone
    傻逼写法 看不懂
    someonedeng
        38
    someonedeng  
       2023-06-10 15:05:47 +08:00
    牛逼 什么东西
    tqyq88
        39
    tqyq88  
       2023-06-10 15:57:14 +08:00
    OP 是不是在政企金融之类的地方工作
    PTLin
        40
    PTLin  
       2023-06-10 16:16:55 +08:00   ❤️ 1
    https://s2.loli.net/2023/06/10/AeXgW2TZIt98E75.png 小小的 rs 震撼,不过这种用法不常见。
    nkidgm
        41
    nkidgm  
       2023-06-10 17:00:55 +08:00
    过度设计,这一定程度上耦合过多的泛型类型,应该分层设计啊。
    Akitora
        42
    Akitora  
       2023-06-10 17:08:04 +08:00
    还以为是 rust
    zhiyu1998
        43
    zhiyu1998  
       2023-06-10 17:33:15 +08:00
    这比 aqs 还难理解
    DinnyXu
        44
    DinnyXu  
       2023-06-10 17:38:34 +08:00
    高级耦合代码,简称屎山......
    zgqq
        45
    zgqq  
       2023-06-10 17:42:32 +08:00
    为了 xx ,而 xx
    token10086
        46
    token10086  
       2023-06-10 17:43:36 +08:00
    楼上的有一个算一个,全在第一层。写这个代码的老哥在大气层。
    这种人还怕老板裁员吗 ?? 手动狗头!
    xuanbg
        47
    xuanbg  
       2023-06-10 19:05:49 +08:00
    这个如果不知道该使用什么类型的话,代码都根本写不下去啊。这个都不能算是过度设计,而是魔怔了呀。
    nullyouraise
        48
    nullyouraise  
       2023-06-10 19:43:24 +08:00
    我之前在 C++里一个模板类带 concept 也写了 30 行的约束……
    AyaseEri
        49
    AyaseEri  
       2023-06-10 19:47:07 +08:00
    这。。。不亚于前端写库那群人做的类型体操。
    liuguangcuican
        50
    liuguangcuican  
       2023-06-10 21:08:38 +08:00
    这代码牛逼的,你们还想着怎么优化代码,怎么写优雅,老板可能背后想着怎么优化你了,这个老哥直接让老板断了这个念想
    GeruzoniAnsasu
        51
    GeruzoniAnsasu  
       2023-06-10 21:18:21 +08:00
    拍平了无非就是 class C <constraint1,constraint2,constraint3,...> 而已

    但放 java 里真的挺蠢的,c++里玩类型体操是因为类型是可被计算的,java 这么搞怕不是邯郸学步把自己忽悠瘸了
    shalk
        52
    shalk  
       2023-06-10 21:27:03 +08:00
    一般类里面,最多泛两三个类型,这么多泛的类型,完全可以拆开来分别设计。

    泛了这么多,全是约束,编译约束可能导致,各种问题,又回来放宽约束
    besscroft
        53
    besscroft  
       2023-06-10 21:51:35 +08:00
    Java 泛型之父,6
    yuekcc
        54
    yuekcc  
       2023-06-10 22:03:33 +08:00
    在 typescript 面前这些都是小 case
    janus77
        55
    janus77  
       2023-06-10 22:51:05 +08:00
    java 是这样的.jpg
    libinglong9
        56
    libinglong9  
       2023-06-10 23:03:35 +08:00
    @beneo 你的回答很 gpt
    fkdtz
        57
    fkdtz  
       2023-06-10 23:47:14 +08:00
    可以但没必要,都 DTO 层面了应该很靠近业务侧了, 业务之间定制化比较高,强行捏合有点过了。不过如果业务之间真的很接近到也无妨吧,反正能保证写一次半年不会改就还行。
    GuardX
        58
    GuardX  
       2023-06-11 00:05:22 +08:00   ❤️ 1
    函数里这么多 Common ,真的很 common 吗?
    Dragonphy
        59
    Dragonphy  
       2023-06-11 00:59:15 +08:00
    需要了解下 Clean Code 的基本概念,代码不可读写得再牛逼那也是拉屎
    realpg
        60
    realpg  
       2023-06-11 02:28:00 +08:00   ❤️ 1
    @vitovan #2
    团队环境写这种代码就离被优化不远了
    byaiu
        61
    byaiu  
       2023-06-11 07:39:18 +08:00
    写 c++的看起来异常的熟悉,这老哥肯定有 c++的背景,有可能还是 boost 教徒!
    RuLaiFo
        62
    RuLaiFo  
       2023-06-11 08:17:41 +08:00
    代码的终极奥义是简单易读,而不是强行设计,只有自己看得懂的就是装 x 。
    lingalonely
        63
    lingalonely  
       2023-06-11 11:53:49 +08:00
    这约束过头,令人窒息,希望这老哥不会被裁,不会离职,否则接收的人不知多花多少时间去挖死山,对是死山不是屎山
    Al0rid4l
        64
    Al0rid4l  
       2023-06-11 14:05:01 +08:00
    有没有必要是一回事, 写得好不好是一回事, 是否很难理解是另一回事.

    前两个不了解具体业务不好评价, 有时候受限于语言表达能力, 泛型参数多也正常, 像 C# BCL 里十几个泛型参数的也不少

    就是否很难理解这个问题而言, C++ Rust TS 选手看这类都很轻松吧
    litchinn
        65
    litchinn  
       2023-06-12 09:00:47 +08:00
    初衷是好的,设计的不行,这个情况使用充血模型会好很多
    CodeCodeStudy
        66
    CodeCodeStudy  
       2023-06-12 09:14:55 +08:00
    既然写成这样,为什么不用 PHP 来写?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2481 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 15:55 · PVG 23:55 · LAX 07:55 · JFK 10:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.