fastjson 和 eventbus 的两个奇葩的特性

2019-05-21 18:03:28 +08:00
 gramyang

fastjson: 只要用到构造器就必须手写一个空的构造器,不然报错。 这个问题貌似 1 点几的时候就有人反馈了,但是到现在还有。。。。

eventbus: 基类注册了 eventbus,其子类必须要有带 @Subscribe 的方法,不然就崩溃。 如果我要去掉一个 fragment 或者 activity 上的事件监听,那我就得不继承基类,或者另外再写一个基类。 查了一下,人家说:你又不接受事件那你注册干嘛??我:好像很有道理。。

3446 次点击
所在节点    Java
14 条回复
chendy
2019-05-21 18:33:23 +08:00
jackson 也是一样,除非用了 @JsonCreator
loshine1992
2019-05-21 18:40:21 +08:00
你只要手写了构造方法,那么该类就不会默认有无参的构造方法了,json 序列化的库基本都是用无参构造生成一个实体,再一个一个根据反射设置参数,没有无参构造方法肯定报错啊。

eventbus 的设计就是这样的,不要在基类里加可能用不到的东西。
liuhuansir
2019-05-21 18:44:34 +08:00
eventbus 本来就不该在基类注册,很多人为了所谓的封装,在基类里写了一大堆东西,又臭又长
Febers
2019-05-21 20:58:55 +08:00
针对第二个,我的做法是提供一个 protected 方法,默认返回 false,然后在父类的 onCreate 代码中判断是否需要注册,如果子类不需要用到 eventBus 就重写该方法返回 false。当然我默认返回 false,毕竟子类用的不多
Febers
2019-05-21 20:59:35 +08:00
@Febers 第一个,默认返回 true
clare0621
2019-05-21 23:49:05 +08:00
@Febers 你这种写法不如直接在子类注册
Febers
2019-05-22 00:57:47 +08:00
@clare0621 哈哈,强迫症吧,感觉 Eventbus 的调用挺长的,还要做判断是否注册过,不如交给父类,子类要么沿用父类,要么重写返回值
gramyang
2019-05-22 07:25:47 +08:00
@Febers 我觉得这种方法挺好啊,所有的框架和设计模式不都是为了减少代码量而存在的吗
MoHen9
2019-05-22 08:59:03 +08:00
我看到在父类注册 EventBus 的,我就感觉很别扭,使用时自己注册不好吗,为了省那么点事。

可以注册一个空的实现,不可能被调用的空方法。也可以判断一下,有返回就注册,没有就不注册
no1xsyzy
2019-05-22 11:01:43 +08:00
@gramyang 几乎所有的设计模式都会让代码量翻倍…… 只不过动脑写的少了,动手写的多了。
这就像是 “四格漫画” 这种既定分镜或者媒体和官方的既定格式 “充分重视……严肃处理……” 一样。

@Febers 难道不是 OnStart 注册,OnStop 解注吗?并且在第一次出现 Subscriber 的类里。
我很难想象一个不需要任何监听任何消息的类继承自一个需要监听消息的类,正如我很难想象任何一小类杯子(即杯子的后代)里面不能装入液体(不继承 “装入液体” 的方法)一样。
你可能说奖杯,但奖杯的父类显然是 “荣誉证明” 或者 “奖品” 之类的。
所以我大胆主张你的问题来自错误的抽象。
southsala
2019-05-22 11:17:32 +08:00
EventBus 基类注册和取消注册前加个 boolean 开关,子类如果接收事件用 set 方法打开开关,这样对其他 Activity 和 Fragment 无感
Febers
2019-05-22 13:40:31 +08:00
@no1xsyzy 如果从“抽象”这个角度出发,这确实是错误的思想~我这么做的原因在于,举个例子,我有一个 BaseActivity,项目中所有 Activity 继承自它,为了让不同的 Activity 专注于自己的业务而不用每次都重写 onCreate setContentView inflate toolbar menu 以及延迟初始化,我选择让 Base 类拥有一个基于 if 判断的实现,然后定义可重写的方法,赋予子类自定义的接口。我通过这样的方式来“抽象”不同 Activity 共有或者需要的行为。

好处在于,一方面子类的代码变少了,不用在每个子 Activity 里面做一些重复的工作,绑定视图只需要重写一个抽象方法 @override int setView() = R.layout.activity.main,如果需要注册时间总线,只需要 @override boolean registerBus() = true ……另一方面,日后更换总线实现(以及其他的实现)的时候也不用在每个已调用的 Activity 中修改,只需要更改 Base 中的代码即可。

个人觉得这是一种编程的习惯,看个人喜好,也谈不上“设计模式”
no1xsyzy
2019-05-22 20:25:44 +08:00
我感觉
一种你可以产生一个新的抽象层 BaseSubscriberActivity 继承自 BaseActivity,并且在这个类里进行所有的 register unregister 等,需要 Subscribe 的继承自 BaseSubscriberActivity,否则继承自 BaseActivity
另一方面,我不太清楚 Java 的修饰器能做到什么程度,我觉得你更需要的是一个 @GeneralSubscriber 的类修饰器
no1xsyzy
2019-05-22 20:57:22 +08:00
@Febers 看上去 Java 要用 annotation 修改 class 的行为似乎很麻烦
感觉是面向切面编程的一部分?相比之下 Python decorator 要方便得多,因为可以任意修改类属性,包括方法(本质上是类的一种静态属性,而 instance.method 会生成对应类方法的 bound method,并且实例可以覆盖它)。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/566302

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX