面向对象
- 我们知道一般编程思想有:面向过程,面向对象,面向切面编程,在软件开发中比重最大的就是面向对象编程了
- 在面向对象中有一个"类"的概念,其实它就是模板
- 面向对象的三要素:继承 封装 多态
- 继承:子类继承父类(公共类)
- 封装: 数据的权限和保密, public, protected, private, 减少耦合,保护特定数据, 数据,接口的权限管理, ES6中不支持, _开头的属性是private
- 多态: 同一接口不同实现, 比如ts中的重写和重载, 保持子类开放性和灵活性,面向接口编程
- 拿js应用来举例
- jQuery是一个class
- $(‘p’)是jQuery的一个实例
- 为何使用面向对象
- 程序执行:顺序,判断,循环 - 结构化
- 面向对象 - 数据结构化,对于计算机,结构化才是最简单的
- 编程应该 简单 & 抽象
- 面向对象是一种思想,实现面向对象需要用到设计模式
软件设计中的设计与设计哲学
1 )何为设计?
- 描述:按照一种思路或标准来实现功能
- 结合《UNIX/LINUX设计哲学》
- 功能相同,可以有不同设计方案来实现
- 伴随需求增加, 设计的作用才能体现出来
2 ) UNIX/LINUX设计哲学
- 准则1: 小即美
- 准则2: 让每个程序只做好一件事
- 准则3: 快速建立原型
- 准则4: 舍弃高效率而取可移植性(通用)
- 准则5: 采用纯文本来存储数据(方便人读,可读性)
- 准则6: 充分利用软件的杠杆效应(软件复用)
- 准则7: 使用shell脚本来提高杠杆效应和可移植性
- 准则8: 避免强制性的用户界面
- 准则9: 让每个程序都称为过滤器
- 小准则: 允许用户定制环境
- 小准则: 尽量使操作系统内核小而轻量化
- 小准则: 使用小写字母并尽量简短
- 小准则: 沉默是金,比如输出数字,有缺省值-1,而非字符串
- 小准则: 各部分之和大于整体,以小的个体组成大的整体
- 小准则: 寻求90%的解决方案,产品面向用户不可能满足100%用户,只需要90%即可
3 ) 演示:沉默是金+每个程序成为过滤器
ls
ls | grep *.json
ls | grep *.json | grep 'package' # 这里可能输出 package.json
ls | grep *.json | grep 'package1' # 这里啥都没输出
ls | grep *.json | grep 'package' | wc -l # 这里是0
ls | grep *.json | grep 'package1' | wc -l # 如果在 ls | grep *.json | grep 'package1' 输出结果为字符串no files, 这里就是1了
4 ) SOLID 5大设计原则
- S 单一职责原则
- O 开放封闭原则
- L 里氏置换原则
- I 接口独立原则
- D 依赖倒置原则:编程要依赖接口而非具体实现
4.1) S原则(单一职责原则)
- 永远都不应该有多于一个原因来改变某个类
- 对于一个类而言,应该仅有一个引起它变化的原因
- 如果一个类拥有了两种职责,那就可以将这个类分成两个类
- 如登录验证:验证用户名和密码,应该分开写两个方法
- 一个程序只做好一件事
- 如果功能过于复杂就拆分开,每个部分保持独立
4.2) O原则(开放封闭原则)
- 对扩展开放,对修改封闭
- 封装的类应该便于扩展,但不要去修改类
- 增加或改动需求时,扩展新代码,而非修改已有代码,尽量用继承或组合的方式来扩展类的功能,而不是直接修改类的代码
- 这是软件设计终极目标
- 举例:
- 需要修改已有代码,成本非常之高,对测试人员巨大的压力
- 多人开发,多个需求,需要修改已有代码,会有很多冲突问题
4.3) L原则(里氏置换原则)
- 父类在使用的过程中,一定能够被子类替换或覆盖
- 在使用方法的时候,如果将父类的引用,换为子类的引用,对整体程序设计来说是没有任何影响的
- 在面向对象中会出场率很高:比如继承和多态
- 但是在前端函数式编程中,出场率和关注度并不高
- 父类能出现的地方子类就能出现
- js中使用较少(弱类型 & 继承使用较少)
4.4) I原则(接口独立原则)
- 一个类与另一个类的关联,应尽量依赖于尽可能小的接口
- 不需要对外暴露,没有实际意义的接口,用户不应该依赖它不需要的接口
- 当对外暴露接口时,如果一个接口是非必要的,应该删除,不应该存在
- 保持接口的单一独立, 避免出现 “胖接口”,尽量不要出现一个函数能解决很多问题,但不是100%不能出现
- js中没有接口(ts中例外),使用较少
- 类似于单一职责原则,这里更关注接口(函数或方法)
4.5) D原则(依赖倒置原则)
- 高层模块不应该依赖于底层模块,他们应该依赖于抽象
- 抽象不应该依赖细节,细节应该依赖抽象
- 应该面向接口编程,不应该面向实现类编程
- 接口中限定了一部分类型,实现类在实现的时候,接口中所有的方法和属性都需要用到
- 实现类中有一些自己实现的方法,是不确定的,不需要关注这部分的实现
- 不是说所有类都要有一个对应的接口,而是说,如果有接口,那就尽量使用接口编程
- 面向接口编程,依赖于抽象而不依赖于具体
- 使用方只关注接口而不关注具体类的实现
- JS中使用较少,没有接口 & 弱类型,但是TS弥补了这个缺陷
5 ) 用前端中的Promise来说明SO
function loadImg(src) {
return new Promise((resolve, reject)=>{
var img = document.createElement('img')
img.onload = function() {
resolve(img)
}
img.onerror = function() {
reject('图片加载失败')
}
img.src = src
})
}
var src = 'http://www.xxx.com/x.png'
loadImg(src)
.then((img)=>{
return img
})
.then((img)=>{
console.log('img.height', img.height)
}).catch((ex)=>{
// 统一捕获异常
console.log(ex)
})
- 单一职责体现,每个then只做一件事,如果想做另一件事,需要添加一个新的then
- 开放封闭体现,如果有新需求,只需要添加新的then即可
- 真正应用时候可通过模块化将各个逻辑拆分到不同文件中
6 )补充原则
-
最少知识原则
- 只与你最直接的对象交流
- 这里最直接的对象是指与自己有直接关联的对象
- 可以用一句话总结,就是高内聚和低耦合:将我们的代码和其他有联系的代码进行最少的关联, 在做系统设计的时候,尽量减少依赖关系
-
组合/聚合复用原则
- 日常程序设计的时候,当扩展类功能时,应优先考虑组合,而非继承,组合优于继承
- 组合的灵活性比继承的要大很多
- 此原则在23种设计模式中频繁使用,如代理,装饰,适配器模式
- 日常程序设计的时候,当扩展类功能时,应优先考虑组合,而非继承,组合优于继承
-
无环依赖原则
- 如果A模块依赖B,B依赖C,C依赖A 此时构成循环依赖
- 应避免出现此种设计,如果出现这种情况,应该使用中介者模式来解决
-
共同封装原则
- 应该将易变的类放在同一个包中,将变化隔离出来
- 该原则是基于开放封闭原则中诞生的一个原则
-
共用重用原则
- 如果重用了包中的一个类,那也就相当于重用了包中的所有类,也就是父类,基类
- 我们要尽可能减少包的大小
-
依赖注入原则
- 又名好莱坞原则:Don’t call me, I’ll call you.
- 也称为控制反转原则
- 不需要主动创建对象,而是由容器帮我们来创建并管理这些对象
- 比如require或import引入的模块,就是依赖注入
-
其他设计原则
- 不重复原则:不要让重复代码到处都是,要让他们足够重用,所以进可能地封装
- 保持它简单与傻瓜
- 保持系统界面简洁,功能实用,操作方便
- 入参和出参不应该太多,了解其作用和副作用
- 高内聚,低耦合
- 模块内部需要做到高内聚,模块之间要做到低耦合
- 关注点分离
- 将一个复杂问题,分解为多个简单问题,逐一解决
- 也就是分而治之,如何进行分离是关键
- 你不需要它
- 完美架构设计者:设计一种程序可包容所有错误,可更好应对更好发展,做了大量适配所有应用的代码,付出远大于收益
- 不要一开始就把系统设计的非常复杂,不要陷入过度设计的深渊
- 应该让系统开开始的时候,设计足够简单,但又不失扩展性
7 ) 从设计到模式
- 设计:设计原则
- 模式:总结出来的模板,可效法的固定的东西
- 设计和模式分开,从设计到模式
424



被折叠的 条评论
为什么被折叠?



