Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[refact] 重新整理项目架构 #84

Open
kengwang opened this issue Jul 12, 2023 · 7 comments
Open

[refact] 重新整理项目架构 #84

kengwang opened this issue Jul 12, 2023 · 7 comments
Assignees
Labels
enhancement New feature or request work in progress Working on it
Milestone

Comments

@kengwang
Copy link
Contributor

kengwang commented Jul 12, 2023

以下是一些个人的想法, 不喜勿喷, 本人是菜鸡一枚.

目前项目结构已经有些混乱, 违反了 SOLID 原则. 可以整理整理项目的架构, 不然代码可维护性降低, 越往之后的开发越困难.

现状: 目前 OutlookService 已经与 Cache 强耦合, 违反了 SRP 原则.

建议将 OutlookService 与 Cache 解耦. OutlookService 的唯一职责应当是与 Outlook 服务器进行通信并返回内容. 不应当在 OutlookService 中放入缓存读写的相关逻辑

  • Cache 应当单独为一层, 不与任何组件进行强耦合, 以提高复用性和单一性.

  • 可以为数据库抽象出 IRepository<TEntity> 接口以便抽象后进行依赖注入.

  • Cache 可在实际 Service 上层, 当无 Cache 或 Cache 过期 或 手动刷新则 向下一级进行获取并存储 Cache

  • ActualMailService / CacheMailService 可以同时继承同一个基类以便可以随时互换

这个基类可以提供查询邮箱各项基本信息的接口 (包括 folder, mails, maildetail 等)

以上仅为个人想法, 不喜勿喷. 本人是菜鸡一枚

@GaN8373
Copy link
Collaborator

GaN8373 commented Jul 13, 2023

最开始我也有一些分开的想法, 但是没有进行. 我之前是考虑让LocalCacheService实现IMailService, 但是落库还是得依赖LocalCacheService或者DbClient.
想不出更好的架构, 不知道其他人的想法如何

@Shomnipotence
Copy link
Contributor

Shomnipotence commented Jul 13, 2023

我对解耦完全赞成,希望你能进行一些工作

@walterlv
Copy link
Contributor

这样可以不?(很粗略)

回答你的疑问:

  1. Cache 在设计中是过滤器链的一部分,过滤器链是抽象的,各缓存和在线获取实现此抽象并链式处理邮件的获取过程
  2. 数据库可能不需要依赖注入,因为其他模块不应该知道邮件是用数据库存储的
  3. 此架构设计和你说的相同,Cache 在 Service 的上层;不过在此架构设计中,是 Cache 的抽象(过滤器)在 Service 的上层
  4. ActualMailService / CacheMailService 的随时互换可能是伪需求;因为从群里的聊天来看,缓存是必不可少的,未来也必将作为重要模块而存在,所以不需要为了互换而做过度设计;不如将缓存直接作为架构设计的一项重要部分,不过进行抽像,避免入侵代码

image

@kengwang kengwang pinned this issue Jul 25, 2023
@kengwang kengwang added enhancement New feature or request work in progress Working on it labels Jul 25, 2023
@kengwang
Copy link
Contributor Author

可能还需要对联系人的头像数据 (byte[]) 也进行缓存

@GaN8373
Copy link
Collaborator

GaN8373 commented Jul 25, 2023

这样可以不?(很粗略)

回答你的疑问:

  1. Cache 在设计中是过滤器链的一部分,过滤器链是抽象的,各缓存和在线获取实现此抽象并链式处理邮件的获取过程
  2. 数据库可能不需要依赖注入,因为其他模块不应该知道邮件是用数据库存储的
  3. 此架构设计和你说的相同,Cache 在 Service 的上层;不过在此架构设计中,是 Cache 的抽象(过滤器)在 Service 的上层
  4. ActualMailService / CacheMailService 的随时互换可能是伪需求;因为从群里的聊天来看,缓存是必不可少的,未来也必将作为重要模块而存在,所以不需要为了互换而做过度设计;不如将缓存直接作为架构设计的一项重要部分,不过进行抽像,避免入侵代码

image

抱歉, 我理解能力不咋样, 是否意味着我们还需要准备一个责任链的实现? 这样看的话似乎本地缓存需要实现IMailService接口, 当做一个源来使用.
还是说按照之前的方式, 缓存的方法直接耦合进IMailService的实现里, 然后以封装好的方法调用

@kengwang
Copy link
Contributor Author

kengwang commented Jul 25, 2023

不需要, UI 层只需要注入读取接口, 由读取接口负责进行 Pipeline 相关的操作.
接口处理后传递到 Pipeline 链, Pipeline 一层层的缓存进行查找, 如果未找到则 hit 上实际的Service(e.g. OutlookService), 之后再从底部回传进 Pipeline, Pipeline 对数据进行同步缓存并返回

个人的理解, 可能有误

@Shomnipotence Shomnipotence added this to the 1 milestone Nov 23, 2023
@Sanlorng
Copy link
Contributor

不需要, UI 层只需要注入读取接口, 由读取接口负责进行 Pipeline 相关的操作.
接口处理后传递到 Pipeline 链, Pipeline 一层层的缓存进行查找, 如果未找到则 hit 上实际的Service(e.g. OutlookService), 之后再从底部回传进 Pipeline, Pipeline 对数据进行同步缓存并返回

个人的理解, 可能有误

我认为在实现上可以靠事件驱动来完成状态监听,最上层用户动作之后,发送一个获取事件从上层传递这个事件往下,中间链路拿到这个事件后往下发送,并监听下一层链路的执行结果或者状态监听(如更新事件)
示例:假设有三层邮件服务,缓存层 -> 数据库 层-> 网络请求层。用户点击刷新按钮后,刷新事件先传递到缓存层,缓存层从缓存中抓取并向数据库层发送刷新事件并监听数据库层的更新完成事件,缓存层如果本身没有数据,则先不向上传递数据更新完成事件,反之则向上传递第一次数据更新完成事件。数据库层收到向下传递的刷新数据的事件后与缓存层相同的处理方式,向下监听网络请求,网络请求是最后一层,如果收到上一层的刷新事件,则进行网络数据的获取并向上传递数据刷新完成事件。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request work in progress Working on it
Projects
None yet
Development

No branches or pull requests

5 participants