对Model抽象的疑惑(Publisher、UnPublisher、Subscriber、Watcher)
Opened this issue · 9 comments
Your question
Publisher、UnPublisher、Subscriber、Watcher这四个类的定义都在model..common.model.store中,所以他们都是存储相关的模型吗?但是他们中又带有业务逻辑,比如:
如果他们是业务模型,但它们似乎又都用户数据传输相关的操作。
另外UnPublisher作为一个模型对象本身是不合适的吧?
Your scenes
存储模型(类DTO对象不应当包好业务逻辑),业务模型应当和存储模型进行分离
Your advice
对存储模型、业务模型做好清晰的抽象
Environment
- SOFARegistry version: 6.1.9
- JVM version (e.g.
java -version
): - OS version (e.g.
uname -a
): - Maven version:
- IDE version:
最早是V5的时候,有watcher、publisher和subscriber等概念,作为几种不同类型的客户端,存储在不同的“Store”里面,这么设计也是最初V5使用了多个线程池,通过task对象进行解耦,所以,将元信息封装在“model”对象中。
而V6我们改版时候,经过压测等手段,发现异步解耦有如下问题:
- 实战下来,过度地一步解耦导致对象之间的关系不明确,很容易混淆,加之没有单测,很容易出现问题
- 性能大坑,无法很好处理IO类任务和计算类任务,以及优先级问题
后来,针对异步队列进行了解耦,但是留下了原有的对象,存储。
再后来,对象本身好像被加了一些定义,这个 @bjxiaojian 比较清楚
- Subscriber作为一个对象,我理解是可以有包含对象自身特性的一些方法的,比如截图中的Subscriber对象是否被推送过,我理解这个不属于具体的业务逻辑;
最早是V5的时候,有watcher、publisher和subscriber等概念,作为几种不同类型的客户端,存储在不同的“Store”里面,这么设计也是最初V5使用了多个线程池,通过task对象进行解耦,所以,将元信息封装在“model”对象中。
而V6我们改版时候,经过压测等手段,发现异步解耦有如下问题:
- 实战下来,过度地一步解耦导致对象之间的关系不明确,很容易混淆,加之没有单测,很容易出现问题
- 性能大坑,无法很好处理IO类任务和计算类任务,以及优先级问题
后来,针对异步队列进行了解耦,但是留下了原有的对象,存储。
再后来,对象本身好像被加了一些定义,这个 @bjxiaojian 比较清楚
- 如果缺少单测应该补充单测,我觉得这个不是问题
- 不知道这一点的性能的坑具体只什么,是对象转换带来的申请内存的开销吗?
- Subscriber作为一个对象,我理解是可以有包含对象自身特性的一些方法的,比如截图中的Subscriber对象是否被推送过,我理解这个不属于具体的业务逻辑;
如果这个对象是common.model.store下的,我建议是不要带有”业务逻辑“。
结合一下DataStore#add方法,Publisher、UnPublisher、Subscriber、Watcher都是能被add到DataStore里面的,以及他们实现了Serializable接口,所以他们应该是数据模型。就像你要像DB插入一行数据,你插入的肯定是数据,而不是数据结构。
最早是V5的时候,有watcher、publisher和subscriber等概念,作为几种不同类型的客户端,存储在不同的“Store”里面,这么设计也是最初V5使用了多个线程池,通过task对象进行解耦,所以,将元信息封装在“model”对象中。
而V6我们改版时候,经过压测等手段,发现异步解耦有如下问题:
- 实战下来,过度地一步解耦导致对象之间的关系不明确,很容易混淆,加之没有单测,很容易出现问题
- 性能大坑,无法很好处理IO类任务和计算类任务,以及优先级问题
后来,针对异步队列进行了解耦,但是留下了原有的对象,存储。
再后来,对象本身好像被加了一些定义,这个 @bjxiaojian 比较清楚
- 如果缺少单测应该补充单测,我觉得这个不是问题
- 不知道这一点的性能的坑具体只什么,是对象转换带来的申请内存的开销吗?
性能的坑具体只什么:这个就是一些很直接的调用,改为要先入队到线程池里面,然后,由线程池执行任务时,触发消费方的执行。无形地让一个纯内存的操作,变成了上下文切换 + 阻塞队列 的操作。性能损耗就在这里。
线程池解耦比较适合一些重IO操作的异步化,内存操作还是同步比较好,放线程池不但不解决问题,还会导致性能损耗。
背景就是这么的。
最早是V5的时候,有watcher、publisher和subscriber等概念,作为几种不同类型的客户端,存储在不同的“Store”里面,这么设计也是最初V5使用了多个线程池,通过task对象进行解耦,所以,将元信息封装在“model”对象中。
而V6我们改版时候,经过压测等手段,发现异步解耦有如下问题:
- 实战下来,过度地一步解耦导致对象之间的关系不明确,很容易混淆,加之没有单测,很容易出现问题
- 性能大坑,无法很好处理IO类任务和计算类任务,以及优先级问题
后来,针对异步队列进行了解耦,但是留下了原有的对象,存储。
再后来,对象本身好像被加了一些定义,这个 @bjxiaojian 比较清楚
- 如果缺少单测应该补充单测,我觉得这个不是问题
- 不知道这一点的性能的坑具体只什么,是对象转换带来的申请内存的开销吗?
性能的坑具体只什么:这个就是一些很直接的调用,改为要先入队到线程池里面,然后,由线程池执行任务时,触发消费方的执行。无形地让一个纯内存的操作,变成了上下文切换 + 阻塞队列 的操作。性能损耗就在这里。
线程池解耦比较适合一些重IO操作的异步化,内存操作还是同步比较好,放线程池不但不解决问题,还会导致性能损耗。
背景就是这么的。
嗯 理解,不过这个应该跟这里的模型抽象没有太多的关系。模型并不会一定要绑定在异步的模式上。
Publisher、UnPublisher、Subscriber、Watcher,其中UnPublisher甚至不是一个名词
Publisher、UnPublisher、Subscriber、Watcher 这几个是data和session上存储的具体业务对象,UnPublisher 是 UnRegister这个动作生产的一个对象。
对于一个Subscriber的对象,isPushed也是这个对象的其中一个属性,这个不是业务逻辑,而是标识Subscriber对象本身的一个属性。只不过代码中没有显性定义一个isPushed,而是通过 pushedVersion 来同时表达isPushed。