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

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

documentChanged
shapeChanged
存储的容量限制与安全
数据变更
对象 ID
存储的容量限制与安全
数据变更
Model 层的核心变化
使用 localStorage 技术
需要在浏览器端进行持久化的原因
结语
浏览器端持久化
补充一讲裸写 MVP 版本的画图程序
引入 MVC 架构
使用 class 关键字
移动图形
删除图形
修改图形样式
创建各类图形
选择全局的图形样式
与服务端连接
MVC 模式
对 JavaScript 的使用
画图程序基本功能
实战(三):怎么设计一个“画图”程序?
参考文章

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

你好,我是七牛云许式伟。
前面的两节课结束后,我们的画图程序已经基本实用。它有如下功能:
可以选择全局的图形样式(lineWidth、lineColor、fillColor);
可以以全局的图形样式来创建各类图形(Path、FreePath、Line、Rect、Ellipse、Circle);
可以选择已经创建的图形,并修改其图形样式;
可以删除选择的图形;
可以移动选择的图形。
前面有一些同学的反馈,我这里想回答一下。
有一个反馈是对 JavaScript 的使用,我为什么会用 class 关键字。
这是因为我不太希望这是一篇某个语言的教程,我选择的是如何用最接近大家思维的表达方式来表达程序逻辑,你就算没有系统学过 JavaScript,也应该能够理解这段程序想要做什么。
另外有一个反馈,是希望我不要一上来就从 MVC 这种模式讲起,而是如果没有 MVC,我们用最基础的裸写代码,会写出一个什么样的程序来,里面有哪些弊端,从而引入 MVC 来让程序架构变得更加清晰,功能之间解耦。
这个意见我觉得是比较中肯的,后面我们会补充一讲来裸写 MVP 版本的画图程序。
今天我们开始进入“实战:怎么设计一个‘画图’程序”的第三讲,怎么和服务端连接。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了如何设计一个“画图”程序,并重点讨论了如何在浏览器端进行持久化。作者首先解释了为什么需要在浏览器端进行持久化,以及选择传统的localStorage技术而非PWA的原因。接着详细介绍了对Model层的核心变化,包括引入对象ID、数据变更的分类和处理、存储容量限制与安全等方面的内容。作者还提到了未来支持多租户的隐私泄漏风险,并提出了在用户帐号登出时清空所有localStorage中的文档来解决这一问题。最后,作者表示将在下一讲继续实战一个联网版本的画图程序。整体而言,本文深入浅出地介绍了“画图”程序的设计和浏览器端持久化的相关技术细节,对于想要深入了解该领域的读者具有一定的参考价值。

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

全部留言(16)

  • 最新
  • 精选
  • 风清扬
    老师,localid可以理解为服务端id,display id是客户端id吗?displayid记录客服端用户操作轨迹,每次同步后,如果用户修改,则display id变更为下一个。而localid始终不变,与服务端同步数据时,用的也是它。

    作者回复: localID 是这篇文档在本地的唯一id,本地是指该浏览器。displayID 有两个可能:一个是创建该文档之初,会有一个临时id,其实就是 t<localID>。另一个是这篇文档被同步到服务端,服务端返回它为这篇文档分配的id。

    2019-07-26
    8
  • Bing573
    我们最近在做一款可视化编辑器时,整个文档是采用的JSON格式存储的。由于没采用分层,所以每次有任何改动都需要保存整个文档。但程序在结构和操作上感觉比分层这种方式简单,对可视元素的操作反映为对JSON的操作也很直观,而且每次保存整个文档似乎也没什么不妥,所以不太理解为何需要采用分层的形式?

    作者回复: 你之所以觉得没必要分层,核心原因是dom比较简单,就一个json,所以业务逻辑也不会复杂到哪里去,直接以json操作接口作为dom的操作接口了。在简单应用中这种情况下不分层问题不会特别大。

    2019-10-14
    6
  • 笛神
    希望老师可以将这几讲的内容用图形表达出来,分为哪几层,每一层职责如何,关系如何,这样理解起来比较形象一点

    作者回复: 如果觉得比较难理解,可以先看 32 讲里面给出的裸写代码,它不分mvc,所有代码都在一起。

    2019-09-10
    2
  • 不温暖啊不纯良
    加入shapeId和documentId是为了局部更新吗?局部更新是以图层为单位更新的,每次浏览器刷新,这些被在本地缓存的图形就会重新绘制,达到保存的效果. 我仔细看了v27的代码,dom.js里面就是对业务的定义.在view.js中看到调用事件.第一次见到js代码还能这么写,简直就像java里面的实体,的确很容易就理解业务轮廓,代码部分还没看完,但看老师写的代码,我长见识了.

    作者回复: 这样写大部分代码和界面无关 耦合最低

    2021-04-15
    1
  • 剑八
    model层数据变化怎么通知view层?

    作者回复: 事件

    2019-08-02
    1
  • 路伴友行
    看了架构整洁之道这本书,不知道大佬会不会讲整洁架构

    作者回复: 会讲,第四章专门谈架构。我们前面几章也会穿插架构的话题

    2019-07-26
    1
  • 有铭
    localID倒是能理解,其实就是这个文件本身,一旦建立,就不动了,但是displayID会变化?每改一次就会变吗?那这东西是不是有点类似git等版本管理工具的提交版本号?是这个意思吗?也就是说其实你支持回退能力

    作者回复: 不是每改一次会变,只有两个状态,一个是没有连上服务器时的id,一个是连上服务器后

    2019-07-26
    1
  • 瓜瓜
    func handleDefault(w http.ResponseWriter, req *http.Request) { if req.URL.Path == "/" { http.ServeFile(w, req, "www/index.htm") return } req.URL.RawQuery = "" // skip "?params" wwwServer.ServeHTTP(w, req) } 用断点调试也走到这个方法里面了,但是页面上还是显示404 page not found,我调试的是v27分之

    作者回复: 要看下程序当前目录是在哪里。正确的当前目录需要设置为www目录的父目录。

    2020-01-17
  • 瓜瓜
    GOROOT=D:\Go #gosetup GOPATH=C:\Users\XXX\go #gosetup D:\Go\bin\go.exe build -o C:\Users\XXX\AppData\Local\Temp\___go_build_main_go.exe D:\git\github\qpaint\paintweb\main.go #gosetup C:\Users\XXX\AppData\Local\Temp\___go_build_main_go.exe #gosetup 我在idea中启动后,为什么是报404 page not found 是哪里配置不正确吗??

    作者回复: 要看下程序当前目录是在哪里。正确的当前目录需要设置为www目录的父目录。

    2020-01-17
    3
  • 黄伟洪
    许先生的课,真是收益匪浅!
    2019-07-28
    14
收起评论
显示
设置
留言
16
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部