我们知道需求规格说明书(SRS)落地之后, 就要开始着手系统设计了,看一下这个系统该如何来设计,并且如何实现。学习系统设计之前,需要先了解系统设计有哪些分类。
系统设计的分类如下
- 界面设计
- 结构化设计
- 面向对象设计(最重要)
1、界面设计
界面设计也叫做人机界面设计,属于系统与用户交互的纽带。而人机界面设计在架构师考试中相对来说考得比较浅,我们了解一下人机界面设计得一些理念即可。
- 置于用户控制之下
- 以不强迫用户进入不必要的或不希望的动作的方式来定义交互方式
- 简单来说,就是用户点了什么,预期的结果就是什么
- 有些网站有那种您需要点多次才能进去的情况,第一次始终进的是广告,第二次才能看到对应的资源。这就违反了这个原则,从而让用户强制进广告让网站盈利。
- 提供灵活的交互
- 允许用户交互可以被中断或者撤销
- 不然某个操作非常耗时,不小心点错了,但是不能中断,那就是用户体验不好。
- 当技能级别增加时可以使交互流水化并允许定制交互
- 使用户隔离内部技术细节
- 用户不需要了解你用了哪些技术,关注的只是能不能快速使用,所以要对用户隔离技术细节,直接上手操作即可。
- 设计应允许用户和出现在屏幕上的对象直接交互
- 减少用户得记忆负担
- 减少对短期记忆的要求
- 不可能使用你的系统,还得先看一下帮助文档,那就是用户体验不好
- 建立有意义的缺省
- 某些东西不需要用户填,设置默认值可以让用户少填一点
- 定义直觉性的捷径
- 定义某些公用的符号 比如放大镜图标就是放大的意思,×符号就是关闭的意思等。
- 以不断进展的方式揭示信息
- 保持界面的一致性
- 允许用户将当前任务放入有意义的语境
- 在应用系列内保持一致性
- 如过去的交互模型已建立起了用户期望,除非有迫不得已的理由,不哟啊改变它。
人机界面上设计考察的深度不是很深,了解到这里就可以了。
2、结构化设计
结构化设计分为概要设计和详细设计(一般已经被面向对象设计取代了)。
概要设计:对应的是模块的划分,模块接口的设计。对应后面的集成测试(把各个模块集合起来测接口)。
详细设计:是基于概要设计已经把很多东西分成小的块,也就是分成了对应的函数了,对函数内部进行具体流程的设计或算法的设计就叫做详细设计。一般针对的是模块内。
详细设计的基本思想
- 抽象化
- 自顶向下,逐步求精
- 因为是结构化的,也就是面向过程,所以是自顶向下设计
- 信息隐蔽
- 同样是需要去调用接口,而不是直接操作实现类
- 模块独立(高内聚、低耦合)
高内聚(内聚程度从上到下逐渐降低)
- 功能内聚(内聚程度最高)
- 完成一个单一功能,各个部分协同工作,缺一不可。对应单一职责原则,就是一个类实现的功能月单一越好,否则会指责过重,啥都要它做。
- 顺序内聚
- 处理袁术相关,而且必须顺序执行
- 通信内聚
- 所有处理元素集中在一个数据结构的区域上
- 过程内聚
- 处理元素相关,而且必须按也顶的次序执行
- 瞬时内聚(时间内聚)
- 所包含的任务必须在同一时间间隔内执行
- 逻辑内聚
- 完成逻辑上相关的一组任务
- 偶然内聚(巧合内聚)
- 完成一组没有关系或松散关系的任务
低耦合(耦合程度从上到下逐渐升高)
- 非直接耦合
- 两个模块直接没有直接关系,它们之间的联系完全是通过主模块的控制和调用来实现的
- 数据耦合
- 一组模块借助参数表传递简单数据
- 标记耦合
- 一组模块通过参数传递记录信息(数据结构)
- 控制耦合
- 模块之间传递的信息中包含了控制模块内部逻辑的信息
- 外部耦合
- 一组模块都访问同一全局变量,而且不是通过参数传递该全局变量的信息
- 公共耦合
- 多个模块都访问一个公共数据环境
- 内部耦合
- 一个哦快直接访问宁一个模块的内部数据,一个模块不通过正常入口转到另一个魔魁啊内部。两个模块有一部分代码重叠,一个模块多个入口。
高内聚,低耦合,意思就是内聚程度越高越好,耦合程度越低越好。
结构化设计的基本原则
- 保持模块的大小适中
- 这个适中的尺度不好确认,也就是说模块的职责不能过重
- 尽可能减少调用的深度
- 调用深度过深会导致栈内存占用较多,一般不超过七层,递归除外
- 多扇入,少扇出
- 模块的独立性很好,多扇入表示调用该模块的应用比较多。少扇出表示本模块调用其他模块较少,意味着该模块功能比较独立,不依赖其他模块,依赖多了就是高耦合了
- 单入口,单出口
- 不容易出错,入口出口都单一
- 模块的作用域应该在模块之内
- 尽量使用局部变量,作用域就可控。全局变量可能其他模块也会修改
- 功能应该是可以预测的
结构化设计这些知识了解就行,不用深究。
3、面向对象设计(重要)
3.1、设计原则
- 单一职责原则
- 设计目的单一的类
- 也就是设计类时,它只做自己该做的时,不要在类里面设计太多的东西,从而达到高内聚,低耦合
- 开放-封闭原则
- 对扩展开发,对修改关闭
- 比如我们新增或修改一个功能时,我们最好新增一个类来操作,把逻辑都写在新的类里面,然后再原来要修改的地方,直接调用这个类的方法。这样就较少了代码的修改,从而减少了出现错误的风险。
- 再比如:我们设计的时候用接口设计,接口分别有多找那个实现,我们要新增一种实现,就新增一个接口实现类就可以了,然后使用SPI切换一个接口的具体实现。这就是对扩展开放,对修改关闭(尽量的减少直接修改代码)
- 里氏(Liskov)替换原则
- 子类可以替换父类
- 子类继承了父类的所有特性,父类出现的地方可以使用子类替换它。
- 依赖倒置原则
- 要依赖于抽象,而不是具体实现。针对接口编成,不要针对实现编程。
- 为什么针对接口编程就变成了依赖倒置原则呢
- 因为原本是依赖实现类,现在依赖的是实现类的接口。以前是A->B,A->C, B->D, C->E这种上层调用下层,如果下层的方法改变了,那么上层得跟着改变,特麻烦。面向对象就在上层定义接口,让下层去实现上层的接口。就变成了下层依赖于上层的接口,这样看依赖关系就倒置了。
- 接口隔离原则
- 使用多个专用接口比使用单一的总接口要好
- 组合重用原则
- 要尽量使用组合,而不是集成关系达到重用目的。
- 继承是一种紧耦合,而我们不希望紧耦合。不然会导致父类修改了什么,所有的子类都需要改。
- 迪米特(Demter)原则(最少知识原则)
- 一个对象应当对其他对象尽可能少的了解
- 说白了,就是使用private这类关键字,将自己对象的属性封装起来,避免被其他类非法修改。只能通过统一的setter或者getter来进行操作。
3.2、设计模式的概念
什么是模式?
模式通俗来讲就是套路,比如武侠小说跳悬崖之后必有奇遇,这就是一套套路,也是一种模式。
很多时候我们会有一些模式化的东西,却解决一些现有的问题,是一种很不错的策略,这就是设计模式。
设计模式的概念
- 架构模式(高层次)
- 软件设计中的高层决策,例如C/S结构就属于架构哦是,架构模式反映了开发软件系统过程中所作的基本设计决策。
- 设计模式(中层次)
- 主要关注软件系统的设计,与具体的实现语言无关
- 惯用法(低层次)
- 最低层次的模式,关注软件系统的设计与实现,实现时通过某种特定的程序设计语言来描述构建与构建之间的关系。每种编程语言都有它自己特定的模式,即语言的惯用法。例如引用-计数就是C++语言中的一种惯用法。
惯用法和设计模式最大的区别就是是否跟计算机语言相关。
4、小结
从上面我们说明了系统设计的一些概念,也说到了设计模式的概念,上面最重要的就是面向对象的设计原则。接下来就需要详细说明23种设计模式了,下次再写吧!加油!