许式伟的架构课
许式伟
七牛云CEO
立即订阅
20237 人已学习
课程目录
已更新 75 讲 / 共 87 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 怎样成长为优秀的软件架构师?
免费
基础平台篇 (21讲)
01 | 架构设计的宏观视角
02 | 大厦基石:无生有,有生万物
03 | 汇编:编程语言的诞生
04 | 编程语言的进化
05 | 思考题解读:如何实现可自我迭代的计算机?
06 | 操作系统进场
07 | 软件运行机制及内存管理
08 | 操作系统内核与编程接口
09 | 外存管理与文件系统
10 | 输入和输出设备:交互的演进
11 | 多任务:进程、线程与协程
12 | 进程内协同:同步、互斥与通讯
13 | 进程间的同步互斥、资源共享与通讯
14 | IP 网络:连接世界的桥梁
15 | 可编程的互联网世界
16 | 安全管理:数字世界的守护
17 | 架构:需求分析 (上)
18 | 架构:需求分析 (下) · 实战案例
19 | 基础平台篇:回顾与总结
加餐 | 我看Facebook发币(上):区块链、比特币与Libra币
加餐 | 我看Facebook发币(下):深入浅出理解 Libra 币
桌面开发篇 (16讲)
20 | 桌面开发的宏观视角
21 | 图形界面程序的框架
22 | 桌面程序的架构建议
23 | Web开发:浏览器、小程序与PWA
24 | 跨平台与 Web 开发的建议
25 | 桌面开发的未来
26 | 实战(一):怎么设计一个“画图”程序?
27 | 实战(二):怎么设计一个“画图”程序?
28 | 实战(三):怎么设计一个“画图”程序?
29 | 实战(四):怎么设计一个“画图”程序?
30 | 实战(五):怎么设计一个“画图”程序?
31 | 辅助界面元素的架构设计
课外阅读 | 从《孙子兵法》看底层的自然法则
加餐 | 想当架构师,我需要成为“全才”吗?
32 | 架构:系统的概要设计
33 | 桌面开发篇:回顾与总结
服务端开发篇 (14讲)
34 | 服务端开发的宏观视角
35 | 流量调度与负载均衡
36 | 业务状态与存储中间件
37 | 键值存储与数据库
38 | 文件系统与对象存储
39 | 存储与缓存
40 | 服务端的业务架构建议
41 | 实战(一):“画图”程序后端实战
42 | 实战(二):“画图”程序后端实战
43 | 实战(三):“画图”程序后端实战
44 | 实战(四):“画图”程序后端实战
45 | 架构:怎么做详细设计?
46 | 服务端开发篇:回顾与总结
加餐 | 如何做HTTP服务的测试?
服务治理篇 (11讲)
47 | 服务治理的宏观视角
48 | 事务与工程:什么是工程师思维?
49 | 发布、升级与版本管理
50 | 日志、监控与报警
加餐 | 怎么保障发布的效率与质量?
51 | 故障域与故障预案
52 | 故障排查与根因分析
53 | 过载保护与容量规划
54 | 业务的可支持性与持续运营
55 | 云计算、容器革命与服务端的未来
56 | 服务治理篇:回顾与总结
架构思维篇 (12讲)
57 | 心性:架构师的修炼之道
用户故事 | 站在更高的视角看架构
58 | 如何判断架构设计的优劣?
59 | 少谈点框架,多谈点业务
60 | 架构分解:边界,不断重新审视边界
加餐 | 实战:“画图程序” 的整体架构
61 | 全局性功能的架构设计
62 | 重新认识开闭原则 (OCP)
63 | 接口设计的准则
64 | 不断完善的架构范式
65 | 架构范式:文本处理
66 | 架构老化与重构
许式伟的架构课
登录|注册

60 | 架构分解:边界,不断重新审视边界

许式伟 2019-11-26
你好,我是七牛云许式伟。
在上一讲 “59 | 少谈点框架,多谈点业务” 中,我们强调:
架构就是业务的正交分解。每个模块都有它自己的业务。
这里我们说的模块是一种泛指,它包括:函数、类、接口、包、子系统、网络服务程序、桌面程序等等。
接口是业务的抽象,同时也是它与使用方的耦合方式。在业务分解的过程中,我们需要认真审视模块的接口,发现其中 “过度的(或多余的)” 约束条件,把它提高到足够通用的、普适的场景来看。

IO 子系统的需求与初始架构

这样说太抽象了,今天我们拿一个实际的例子来说明我们在审视模块的业务边界时,需要用什么样的思维方式来思考。
我们选的例子,是办公软件的 IO 子系统。从需求来说,我们首先考虑支持的是:
读盘、存盘;
剪贴板的拷贝(存盘)、粘贴(读盘)。
读盘功能不只是要能够加载自定义格式的文件,也要支持业界主流的文件格式,如:
Word 文档、RTF 文档;
HTML 文档、纯文本文档。
存盘功能更复杂一些,它不只是要支持保存为以上基于文本逻辑的流式文档,还要支持基于分页显示的文档格式,如:
PDF 文档;
PS 文档。
对于这样的业务需求,我们应该怎么做架构设计?
我第一次看到的设计大概是这样的:
type Span struct {
...
SaveWord(ctx *SaveWordContext) error
SaveRTF(ctx *SaveRTFContext) error
LoadWord(ctx *LoadWordContext) error
LoadRTF(ctx *LoadRTFContext) error
}
type Paragraph struct {
...
SpanCount() int
GetSpan(i int) *Span
SaveWord(ctx *SaveWordContext) error
SaveRTF(ctx *SaveRTFContext) error
LoadWord(ctx *LoadWordContext) error
LoadRTF(ctx *LoadRTFContext) error
}
type TextPool struct {
...
ParagraphCount() int
GetParagraph(i int) *Paragraph
SaveWord(ctx *SaveWordContext) error
SaveRTF(ctx *SaveRTFContext) error
LoadWord(ctx *LoadWordContext) error
LoadRTF(ctx *LoadRTFContext) error
}
type Document struct {
...
TextPool() *TextPool
SaveWord(stg IStorage) error
SaveRTF(f *os.File) error
SaveFile(file string, format string) error
LoadWord(stg IStorage) error
LoadRTF(f *os.File) error
LoadFile(file string) error
}
从上面的设计可以看出,读盘存盘的代码散落在核心系统的各处,几乎每个类都需要进行相关的修改。这类功能我们把它叫做 “全局性功能”。我们下一讲将专门讨论全局性功能怎么做设计。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《许式伟的架构课》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(10)

  • Sam
    许大,请教您一个问题。文中提到的如下代码片段:
    func Save(src interface{}, format string, doc IoDocument) error
    func Load(src interface{}, doc IoDocument) (format string, err error)
    其中format参数有何用意,麻烦指点下。
    第二个: func Save(dest interface{}, format string, doc IoDocument) error
    我没想到改造方法,只想到了增加了 func Export(dest interface{}, format string, doc ViewDocument) error,这种方式,感觉好Low

    作者回复: 1、format就是要保存的文件格式;
    2、其实你说的是一个好方法,我也用的是这个方法。

    2019-11-27
    2
  • 丁丁历险记
    这下好了,满脑子架构就是业务的正交分解了。。。。。
    2019-11-26
    2
  • 许式伟-七牛云(已满)
    其实,这里面有一个隐含的决策没有交代,为什么有引入 IO DOM,直接拿核心系统的 DOM 来作为 IO 系统依赖行不行?欢迎留言探讨。
    2019-11-26
    1
  • 越来越有味,这系列文章需要反复研究
    2019-11-26
    1
  • Bachue Zhou
    感觉什么约束都没有的 interface{} 不该出现在重要的接口里 不可能真的什么约束都没有 肯定会要求实现某些接口或者约定了某种反射方式 还是应该在接口里体现出具体的约束细节

    作者回复: 是这样。大部分情况下不应该用 any 类型,除非有什么让人信服的特殊理由。

    2019-12-07
  • 丁丁历险记
    最近买了打印机,pdf 打出来模糊,wps pdf 转word 想的挺好,实施起来各种坑。
    思来想去,还是github 上找找pdf 转html的代码,毕竟ai 很成熟了。
    然后html 打印。
    毕竟对开发来说,调html样式 比编写word 容易太多。

    作者回复: pdf 转 word 的确比较复杂,这里没有讨论。

    2019-11-26
  • 老大,go语言的入门书介绍一下,go语言擅长做啥了

    作者回复: 网上随意买一本都可以,Go语法确定性较强,掌握门槛比较低,关键在用起来。Go能够用的领域可以很广泛,主要做后端开发,单我甚至也用它做过游戏。

    2019-11-26
  • 落石
    func Save(dest interface{}, format string, func () interface{} docmentLoader) error

    由调用方决定 document 的类型。
    1. 将document也调整为父子类的形式。但隐约感觉到老师好像不太赞同继承?
    2. 或者在调用时强转为 SaveWord 或 SavePDF 中的 IoDocument 和 ViewDocument

    作者回复: 仔细想想,是否可以解决问题

    2019-11-26
  • Aaron Cheung
    模块边界 受教了

    期待架构思维实战篇👍
    2019-11-26
  • leslie
    期待老师的《架构思维设计》:希望老师可以在阳历年之前分享出来,这样可以更好的用在自己的将来新项目上。
        一路跟着老师学习还是觉得受益匪浅,许多思路梳理清楚了。看到很多扩展性的坑、边界有时需要自己不断的调整到更高的高度,完成了一个类似看到了、审清还要做清,例如:架构的分级乱、接口乱、代码的效率/规范化乱、执行乱。
          整体架构的思维设计确实可以梳理出许多:老师讲《中间件存储》时,根据老师的内容梳理清楚了数据系统这块,总体的架构思维还是期待老师的加课能够提供不一样的思维方式吧,这样自己可以做的更好。期待老师的《架构思维设计》,谢谢老师的分享。
    2019-11-26
收起评论
10
返回
顶部