许式伟的架构课
许式伟
七牛云 CEO
84945 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 89 讲
许式伟的架构课
15
15
1.0x
00:00/00:00
登录|注册

29 | 实战(四):怎么设计一个“画图”程序?

Controller 层
Model 层
删除 drawing 文档的一个 shape
修改 drawing 文档中的一个 shape 的 zorder 次序
修改 drawing 文档中的一个 shape
取 drawing 文档中的一个 shape
在 drawing 文档中创建一个新 shape
删除 drawing 文档
获取 drawing 文档
创建新 drawing 文档
架构角度
Mock 版本的服务端程序
版本升级
重试的友好性
网络协议定义范式
服务端功能
浏览器端的 DOM 模型
多租户带授权的场景
结语
第一个实现版本
网络协议
画图程序网络协议设计
标题:29 | 实战(四):怎么设计一个“画图”程序?
参考文章

该思维导图由 AI 生成,仅供参考

你好,我是七牛云许式伟。
今天继续我们的画图程序。上一讲完成后,我们的画图程序不只是功能实用,并且还支持了离线编辑与存储。
今天我们开始考虑服务端。
我们从哪里开始?
第一步,我们要考虑的是网络协议。

网络协议

为了简化,我们暂时不考虑多租户带授权的场景。后面我们在下一章服务端开发篇会继续实战这个画图程序,将其改造为多租户。
在浏览器中,一个浏览器的页面编辑的是一个文档,不同页面编辑不同的文档。所以在我们的浏览器端的 dom.js 里面,大家可以看到,我们的 DOM 模型是单文档的设计。
但显然,服务端和浏览器端这一点是不同的,就算没有多租户,但是多文档是跑不了的。我们不妨把 QPaint 的文档叫 drawing,如此服务端的功能基本上是以下这些:
创建新 drawing 文档;
获取 drawing 文档;
删除 drawing 文档;
在 drawing 文档中创建一个新 shape;
取 drawing 文档中的一个 shape;
修改 drawing 文档中的一个 shape,包括移动位置、修改图形样式;
修改 drawing 文档中的一个 shape 的 zorder 次序(浏览器端未实现);
删除 drawing 文档的一个 shape。
完整的网络协议见下表:
其中<Shape>是这样的:
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

这篇文章深入探讨了设计一个“画图”程序所需考虑的技术细节,主要围绕网络协议的设计和版本管理展开讨论。作者首先介绍了网络协议的设计原则,包括创建、获取、删除文档以及在文档中创建、获取、修改和删除形状等功能。重点讨论了网络协议设计中的重试友好性和业务相关细节,并提到了协议的版本管理问题,介绍了逐步升级版本的好处。文章还探讨了服务端实现的可能性,包括常规实现和Mock版本的服务端程序,强调了Mock版本在团队工作并行和快速验证网络协议有效性方面的优势。作者还详细介绍了服务端程序的架构设计和实现,包括Model层和Controller层的功能和代码示例。总体而言,本文对于想要了解网络协议设计和版本管理的读者具有一定的参考价值,尤其是对于业务逻辑相关的部分理解起来相对容易。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《许式伟的架构课》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(18)

  • 最新
  • 精选
  • 且看海棠笑一回
    进入“画图”程序实战后,文章从一开始的高屋建瓴逐渐进入到架构具体的繁枝细节,每一章的内容都需要很长时间才能消化,也意识到自己在宏观架构层面代码应该如何有效组织的能力非常欠缺。 留言区和收藏数相比前面章节也少了许多,不知道到底有多少同学可以坚持到这里,架构之路任重道远,许老师加油,大家一起加油!

    作者回复: 一起加油!下一讲结束实战,不过也是比较难的一块硬骨头。我后面会反复扳开来谈这个案例。

    2019-07-31
    2
    15
  • 有铭
    老师,我对你说的那个“网络协议的版本升级问题”很有兴趣,虽然你只提到了其中一种,就是在url中加版本号v1,v2这种形式,但是我看过不少文章,有不少文章指责在url上添加版本号是非常典型的破坏REST语义的行为,对网络协议的版本升级问题,似乎没有一个特别好的方案,无论是写在url上,还是写在queryString上,都有各自的问题。这个问题能否深入探讨一下

    作者回复: 我只认这种,相对优雅

    2019-07-30
    5
    7
  • tingye
    文中网络协议改成接口协议似乎更好理解

    作者回复: 网络协议的确是一个有歧义的词

    2019-07-30
    3
    7
  • 风清扬
    老师,咱们采用的应该是restful协议,那为啥修改不用put,而是跟新建同一个post呢?这样做路由层区分怎么做呢?

    作者回复: 路由怎么解释可以看一下go代码。至于用post还是put,这个一定程度来说只是一个习惯问题

    2019-07-30
    4
  • 立耳
    API版本是不是也可以放到Header中来完成,类似于UUID,这样接口形式基本保持一致?

    作者回复: 是一个可能性,只不过这意味着url route模块需要根据http header来路由,这大部分标准url route可能并不支持,需要自己实现。

    2019-08-16
    3
  • Geek_88604f
    简单梳理一下服务端的流程: sharp.go定义了各种图形相关的结构体,drawing.go描述了doc的组成、操作drawing 和sharp的各种方法。 service.go定义了服务端实际的处理流程,首先初始化doc对象,然后创建service实例并将doc对象作为service的参数传入以便操作doc对象。接下来启动http端口侦听,指定了侦听端口和请求处理handle。这样当客户端向服务端发送请求时,侦听端口就会接收到。服务端接收到请求后,调用ServerHTTP在内部进行路由解析并调用对应的请求处理函数。 在具体请求函数内部又调用了doc对象的相关处理函数实现对模型数据的操作。

    作者回复: 👍

    2019-08-17
    2
  • Charles
    请问许老师,迭代是直接在mock程序上一点点修改实现了吗?等迭代完成,mock程序是否还有存在必要?

    作者回复: 1、看mock和实际程序的差距,两种可能都有;2、mock价值往往是阶段性的,到后期维护协议和正式程序的一致性成本会高于价值,而且往往已经有稳定版本的服务端程序可用

    2019-07-31
    2
  • 闫飞
    稍微较真一点讨论一下RESTful API里面关于verb的用法,因为相关的讨论实在是太多了,google一搜就可以得到一大把。 一种惯例是:把对资源的局部修改是用patch操作的,而post提现的是资源从无到有的创建动作,类似地put操作用来表示移动资源,里面的内容可能不变化。 上面表述的惯用法貌似是一种弱共识,具体例子可参考Kubernetes的API设计。

    作者回复: 确实是弱共识

    2019-08-20
    1
  • 一粟
    请问老师看好GraphQL吗?

    作者回复: 还在理解,目前还没有看清楚趋势

    2019-08-01
    1
  • 不温暖啊不纯良
    在画图程序中,我们的业务封装和实现主要在前端,后端的功能好像就提供了数据的持久化,以及基于持久化的crud操作,但是在我们的开发中,后端负责的事情很多很杂,业务的封装就是一个实体类,所有的处理都在service层完成.以前我觉得这样也代码一点问题都没有,但是学习了架构课后,我才意识到,我以前是在用面向对象语言写面向过程代码.要是能够像老师一样分装业务模型,后端代码也会好些优雅很多. 还有关于重复提交的问题,我的解决办法是利用提交按钮来解决.提交按钮点击后,直到请求响应完成之前都不能再点.

    作者回复: 前半截正解,后半截关于重复提交,可以有更优雅的方案,不需要与前端耦合。

    2021-04-15
收起评论
显示
设置
留言
18
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部