关于软件设计
面试被虐复盘整理。
周二参加了一场面试,大数据部门。二面时面试官问到了许多面向对象编程、类、继承,编程语言未来的发展之类的问题,答得不好。
其实之前对这些名称有一些了解,包括领域驱动设计啊、编程范式、OOP 啊之类的,但是了解的不深入,并且没有一个整体的概念。回家之后把面试官的问题捋顺了一下,查阅部分资料之后,好像最后都指向了一个方向 —— 软件设计。现整理如下:
是什么
软件设计是一门关注长期变化的学问。初学编程的程序员会追求把一个功能实现出来,他无法看到一个软件长期的变化。
算法和软件设计其实是一样的,二者对抗的都是规模问题。算法对抗的是数据的规模,而软件设计对抗的是需求的规模。数据达到一定规模之后,快速排序比插入排序才更有优势;需求达到一定规模之后,面向对象的编程范式会比面向过程更有优势。
模型
软件开发的目的是什么?
是解决由需求带来的问题,解决的结果是一个可以运行的交付物。比如在线购物的需求,通过电商平台这个方案来解决。
软件设计,就是架通需求和解决方案的桥梁!
区别于解决简单的问题,软件的开发往往是一项长期的工作,会有许多人参与其中。在这种情况下,就需要建立起一个统一的结构,以便于所有人都能有一个共同的理解。这就如同建筑中的图纸,懂建筑的人看了之后,就会产生一个统一的认识。
在软件的开发过程中,这种统一的结构就是模型,而软件设计就是要构建出一套模型。
模型,是一个软件的架构。
- 粒度上可大可小;
- 好的模型应该“高内聚、低耦合”;
- 模型可以分层,由底层的模型提供接口,构建出上层的模型。
规范
规范,就是限定了什么样的需求应该以怎样的方式去完成。比如:
- 与业务处理相关的代码,应该体现在领域模型中;
- 与网络连接相关的代码,应该写在网关里;
- 与外部系统集成的代码,需要有防腐层;
- …
显式的、统一的规范可以使项目以一个统一的方式去进行,即便未来设计要演化、规范要调整,项目也要可控得多。
分离关注点
软件开发中最常见一种解决问题的方式就是“分而治之”。大系统拆解为模块,模块再拆分为小功能。值得注意的是,拆解时候要从多维度去考虑,每个维度代表一个关注点,这就是设计中常见的一个说法:分离关注点。
不同的关注点混合在一起可能会带来很多问题,另一方面,分离关注点有助于我们发现不同模块的共性,更好的进行设计。
常见的关注点混淆情况:
- 技术和业务混淆:
- 例子:上游系统以推送的方式向当前系统发消息,但是有可能会丢消息,于是开发人员加了一个补偿机制,来请求丢失的消息。业务量大的时候,补偿机制触发频繁,进一步加大服务器负担。问题点在于,推送消息是通信层面的问题,补偿机制将其带到了业务层面,更好的解决方案是选择一个吞吐量更大的消息队列。
- 不同数据变动方向的混淆:
- 在 Java 应用里,做数据库访问用 Spring Data JPA 好,还是 MyBatis 好。Spring Data JPA 简化了数据库访问,自动生成对应的 SQL 语句,而 MyBatis 则要自己手写 SQL。从本质上说,之所以出现工具选择的困难,是因为他把两种数据使用频率不同的场景混在一起所造成的。如果将前台访问(处理增删改查)和后台访问(统计报表)分开,纠结也就不复存在了。
- …
包括什么
- 程序设计语言
- 模型、接口、运行时
- 编程范式
- 结构化编程
- 面向对象编程
- 函数式编程
- …
- 设计模式
- 发布订阅模式
- …
- 设计原则
- 单一职责
- 开放封闭
- 接口隔离
- …
- 设计方法
- 领域与驱动设计
- 战略设计
- 战术设计
- …
初步学习,大致包括以上几个大方面,每个方面拿出来都够说上半天的,后续每个模块会陆续更新单个的文章。
参考
- 软件设计之美
- 软加设计的哲学