java 板


LINE

※ 引述《sbrhsieh (十年一梦)》之铭言: : : private static Map<Class<? extends IService>, IService> serviceMap = new : : HashMap<Class<? extends IService>, IService>(); : : @SuppressWarnings("unchecked") : : static public <T extends IService> T getService(Class<T> clazz) { : : return (T)serviceMap.get(clazz); : : } : 我不明白第二点的意思。T被限制住一定是传入的Class<T>,这与从 serviceMap 取出 : 一个 value 会是 T 的关联是? : compiler 会给 warning 就是因为它没有办法确定他所产生的 code 能够保证 : 型别上的正确。 : getService method 宣称它会传回完全相容於参数所指定的型别的物件,而其实作 : 是从一个 Map 的 value 而来,依照 serviceMap 的 generics 宣告,只能确定 value : 定是 IService 相容的物件(当然这里不考虑使用 casting 乱搞的行为),getService : 的实作中 compiler 所产生的 guarding code 是没有办法确定它一定能够传回相容於 : 参数所指定的型别,需要你要求 supress warning 并不是莫名其妙的事情。 : 编译器没有在 compile-time 做到型别上的保证,同样地你也没有办法,你会觉得 : 你有信心还是在於你去 reasoning 你的程式流程,认定这样子没错。如果这个 : serviceMap 不是完全由你掌控(比如它从别处而来或是它的 reference 可扩散到 : 其他地方),你就不会认为这个 SupressWarning 是没有疑虑的,不是吗? 恩...我大概懂你想表达的意思了,基本上你是对的,我着眼的地方跟你有点落差 我着眼在於"我认定这个是个black box(很有信心)",而你是着眼於整个面向 扩散的问题我有考虑到,所以基本上跟注册有关的code都会被严格限制在private 这也是为什麽这个系统当初不会搞一个什麽RegisterService啥的 而是把Map跟register()严格的以private禁锢在BaseService的理由之一 这点你也正确地指出来了。 不过既然我们有"这个设计没有扩散的问题 只是可能会有Scaling的问题"的共识的话 (下文您就是回覆关於Scaling的问题) 这部分我想应该我跟你意见是一致的,只是你觉得这设计会有其他面向的问题 这倒是一个我没想过的insignt,谢谢你的指教 "getService()回传值系统只能保证是个IService 我却是逼他转成T (即使他是实作於IService),所以会有warning,而我只是很有信心的设计成他是对的" 这应该就是你所想要表达的概念 : : 这点其实我不太懂为什麽叫做暴露细节 : : 大多数来讲Service都有自己独特的功能,除非像是CRUDService而且仅仅被限制在CRUD : : 我们来分两部分来讲,比方说你提到的以及CRUD,这种Service的特徵是 : : "我服务的介面完全相同,差别仅在於我处理的Bean(我们称为Marsheled Bean)" : :[略] : : 再来看第二种Service : : 这些Service只有部分method是每个Service都相同的 : : 但是各个Service有自己独特的不同,那我们的目标就不是"透过interface操作" : : 我们必须让使用者看到service独有的功能才能做事 : : 就有如我blog里面提到的第一个NameCardService : : 只有他有sort跟getDuplicated,其他Service都没有 : : 这算是恶性的expose吗?我还真的想不到不expose的方法 XD : : 如果你说的是我们应该要有一个INameCardService的话,正好,我们现在的设计有 : 我认为 service(or plugin) 都是可以在 runtime 去抽换的,那麽 client 一定是 : 以 interface 去操作之,不可能在编译期去知道 service 确切实作者(class)。 : 即便不考虑 runtime 抽换 service/plugin,client 要使用到 class name 来取用 : service 的做法,不论是在开发上还是架构设计上,已放弃了许多弹性。 : service 由 interface 来定义它的功能,每个 service 都是一个独立的 : interface,不会有"多种 service 由一个 interface 定义共通部分,然後特定 : service 有的功能就直接将 service 视为特定 class",而是若 service B 比 : service A 多一项功能,就应该有一个 interface 是比 service A interface 多 : 一项功能的 interface 来定义 service B。(多个 service interface 彼此间可以 : 行成一组阶层) : 我提出这一点的目的是:依你的范例来说它是个很单纯的(阳春),可是即便如此你 : 还是用到两个 SupressWarning,这 OK,若你能够验证你的设计定不会出错。 : 可是若考量其他的需求来改良你的设计,当它变得复杂了,你可能会发现利用参数 : 来 infer return type 的做法,变得不太容易写,SupressWarning 越来越难避免 : 且 SupressWarning 会扩散,情况不再是只有你需要 SupressWarning 你确定它是 : 无害的,也许 service 的实作者都需要用到 SupressWarning,那麽你就要要求 : 他们也能够保证他们的 code 的正确性,否则你当初希望 client 可以很简单地 : 取用到有正确编译期型别的目标就失去了。 : *利用 argument 来 infer return type 的做法不算罕见,是不多但我认为这是 : 因为能这样用的场合很有限,要写多这样的设计又不用到 SupressWarning 更是少, : 如果要求实作中所用到的 code(library, core classes)的实作也不使用 : SupressWarning 则更少。 : 在很单纯的应用中的话,想要 client 在取用 service 可以有正确的编译期型别, : 为什麽不考虑由你来写个 Services 这样的 utility class 来给 client 使用。 : class Services { : IServiceA getServiceA(...); : IServiceB getServiceB(...); : ... : } : 由你来提供这些 method 里的 wrapper code。 : 或者是设计像 ServiceRegistry 这种东西,有注册/取得各种 Service 介面的实作品 : 的 method,实际使用注册部分的 code 由你来写,也可以简单做到你要的效果。 这跟设计哲学有关系。 如果我们可以让使用者单单只要继承一个class,接下来他就可以完全使用这些功能 这种把使用者当"设计上的傻瓜"的哲学,在我经验里面会省下很多维护上的麻烦 (类似於qttr1说的爽到你艰苦到我) 按照你的写法的话,使用者或者我,必须去手动帮他们添加一个个的service (我称这种叫做hard-code registry),一定得有一个人做这件事情 而要是我们甚至只要提供一组jar,要人import,然後继承某个class写Service就能搞定 我觉得这是这组机制设计的目的 目前来讲Service使用者"都"不需要Supress这个Warning 拿出来的class直接就是已经转好的class 所以在这个scale目前还没看到你说的问题(也许以後会有?我不敢说那麽肯定XD 但是这也是我要避免的目标 -- 我连使用者转型都有疑虑了 还放warning出来要他们supress? 不可能) 我想说的是 logdown里面用来举例的是个严重简化过的例子 他想表达的仅仅只是一个generic technique,而非一个完整的Service设计概念 是我Service设计概念中的一部分(我在回给您的回覆中有提到我们现行Service是 怎麽跑的,您可以清楚的看到Service因为某些理由,是有自己的独立Interface 比方说我回覆给您的IMasterChannelService) 目前设计上是可以把IService/BaseService包成jar给使用者去跑,把这端一刀切成 Framework端,而使用者要做的是引入这个jar 继承BaseService 然後写自己的ISomeService 不过我想现在我不管怎麽讲,应该都不够清楚 =P 因为其实这篇该说的应该仅仅只是Generic Technique 关於Service的设计上,除了您给的demo code我没办法赞同以外 其实应该在大多数的想法上我跟你都是in the same page 不过您提到的SupressWarning方面的看法面向也是很重要,感谢指教 相信等我有空把真正的Service设计哲学提出大家分享的时候 应该会激起更多的水花 :) 另外有一点我比较困扰的是,很多code其实是以C++ policy based design写出来的 要怎麽把他转成java跟大家一起讨论架构设计 其实对我已经是个很严苛的挑战了(汗) --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 119.14.20.94 ※ 编辑: Killercat 来自: 119.14.20.94 (07/21 16:53)







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:BuyTogether站内搜寻

TOP