很久没有进行纯语言的博客的写作了,这次更多的也就是记录一下自己在编程的过程中的一些整体项目的设计方法。同样也供自己在以后的项目设计中继续进行复用。
由于我的习惯是从0开始写代码,所以基本上很少直接复用别人的代码,当然直接引用的框架包除外。所以基本上,每次的代码设计也都能够发现,差不多都是有比较相同的逻辑的。
而在这个基础上,把一些更好的思考方式和代码组织方式总结起来,将会在以后的 从0手搓代码 提供诸多的方便。
代码目录结构的设计
对于设计一个项目的结构来说,最外层的主体框架还是更加重要的。能够把各种功能模块给清晰的分开,把该放的东西放在该放的地方,不仅有助于代码的茁壮成长,同时也能够让自己更清晰的认识自己的代码。
这里,我常用的一些代码结构如下(当然,基本上在 typescript, java, python, golang, flutter 等语言大概都是通用的):
- 全局层面
- global: 用于放一些全局的文件,例如全局的常量,全局的定义等等。适合放代码中几乎永远不变的东西
- constant: 用于放一些全局的常量
- config: 用于放一些配置相关的文件,例如
xx.json,xx.xml,而解析这些配置文件的代码也可以放到该目录下,用于更方便且清晰的处理这些配置。 - tools: 用于放适用于该项目的一些工具类,如
配置解析工具,文件处理工具,加密解密工具等 - utils: 用于放适用于各个项目的一些工具类,如
字符串处理,数组处理,时间处理,格式验证,日志处理等
- global: 用于放一些全局的文件,例如全局的常量,全局的定义等等。适合放代码中几乎永远不变的东西
- 业务层面
- controller: 用于接收外部的第一级请求和传送内部的最后一级响应,并对请求进行初步处理,对响应做最后一步的处理
- service: 用于进行请求的中间处理,也就是业务的中间处理层
- dao: 数据库处理的接口封装层,用于与数据库进行相应的交互
- sql: 可以放一些常用的代码调用的sql语句
- bean: 也可以叫 entity ,用于放项目中所需要的一些实体对象,用于承载数据的传递
- route: 可以用于放一些路由定义和请求处理逻辑
- middleware: 这里可以放一些内部请求的中间件
- interceptor: 这里可以放一些适合业务层面的拦截器。可以在请求到达controller之前对请求做一些预处理
- aspect: 切面,用于在某个业务流程的过程中插入一个通用的操作,例如在某些函数操作前加一个记录日志的功能,在某些函数操作后加一个自动请求某个api的功能等
命名的设计
对于项目中变量的命令,本着读变量就能够知道这个东西是干什么的原则,变量名要起的更加有意义,从而尽量减少注释的存在。
否则在后边项目进行迭代的过程中,代码内部的逻辑改了,甚至方法名称都改了,但是注释没有改,那么这个项目的维护将会带来越来越麻烦的体验。
当然,最开始的基础注释也还是应该有的,而这个也几乎是不变的东西,是基础。剩下的东西也都是从这个基础上生长出来的,所以这些注释的存在也是有意义的。
而对于变量的命名,不同的语言有着不同的风格,所以下边的这些变量的命名风格将会在我后边的不断积累中继续扩充,现在先放一些已经有的东西
1 | typescript: |
具体内部的逻辑行走
对于程序设计来说,基本上可以理解为从输入到输出这个简单的模式。
而其他的情况都只是在这个基础模式上进行不断的扩充,然后达到整个效果的实现。
以下是我常用的一些逻辑处理方式:
模块之间的消息交互
网页与网页的交互
网页与网页之间进行交互,更多的是用在一个网页套在另一个网页中的情况,也就是 A网页 使用 iframe 套 B网页。
这种情况的出现主要是因为各种网页模块各自独立开发,但是最后又需要套在一起。而模块之间很可能又需要进行相互调用,所以就需要有一种交互模式。
这个时候就可以使用 iframe 提供的 postMessage 方法来进行网页功能之间的调用
而因为网页之间调用更多的只是通过上级网页调用下级网页中的一个功能,不一定涉及到数据的传递,所以基本上使用如下的这种消息传输方式即可。
1 | { |
code 指定要调用的网页中的唯一API,message 可以用作API的 二级子命令。
iframe网页内部接收到这个指令之后,就可以判断要调用的是什么功能,从而做出相应的反应。
实在有数据的时候,可以通过再加一个 data 键,然后继续以 json 的格式组装数据即可。
同样的,iframe网页内部的服务如果调用iframe外部的服务,也可以通过这种方式来进行反向的消息传输。
使用这种方式的话,被调用方其实可以看做是一个后端的服务,接收到消息请求之后,然后做相应的反应就行。
而如果确实是想做成类似于前后端进行 tcp 连接后的同一个会话的交互,那么可以在请求的消息中再加一个 id 键,用于标记是同一个消息。
两端都放一个用于存储消息键的 storage ,用于存储一些上下文信息,收到消息后通过 storage 做一些判断,那么就可以模拟长连接的情况了。
网页与后端的交互
较早的传统模式都是网页与后端集成到一起,像 PHP,JSP 等都是直接在脚本中就嵌套了网页代码。
这种方式虽然很方便,但是缺乏美观性,并不优雅。
所以更好的方式也还是使用前后端分离的情况,两端使用 ajax 去进行请求的交互。
前端的文件可以放到 nginx 进行内容分发,或者放到高速CDN上进行托管,后端的文件只需要提供接口请求即可。
前端传输到后端的数据由于可能存在被盗用的情况,故而应该
这里重要的也还是中间层的 API 组装。设计一个良好的 API 请求接口,无论对于接口调用,还是 API 的后期扩展,都是有着很好的积淀的。
后端与后端的交互
后端之间的交互直接通过各种语言提供的 HTTP 请求组件即可。通过封装一些简单便捷的接口组件,也可以方便后边内部各种情况的扩展。
而在后端,由于可操作的灵活性,所以对于消息的处理可以更加多元化。
例如 A模块 提供了一个请求接口,接收到 B模块 请求的数据。而有很多其他的平台系统希望在 A模块 接收到 B模块 的消息后,也收到这个消息,例如 C模块 。
那么 C模块 就可以在 A模块 注册自己的接口信息(订阅模式)。当 A模块 收到信息后,通过读取存储起来的 C模块的接口信息,就可以给 C模块 发送这个消息了。
而如果 C模块 掉线或者不支持接收某种信息,那么这里也就又有了更多的处理情况了。
具体在后端的处理可以有更多的扩展,这里也将不再详细说明。
输入的请求的处理链
这里是一个通用的流程,具体在做的过程中可能还是需要进行更多的扩充。
对于获取到请求之后,需要对请求先进行相应的校验,然后再去进行
- 本文标题:我的项目设计框架
- 创建时间:2023-10-19 09:09:26
- 本文链接:https://blog.212490197.xyz/article/blog/my-project-design-framework/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!