设计模式: 面向对象思想,软件设计原则与设计模式之间的关系

面向对象

  • 我们知道一般编程思想有:面向过程,面向对象,面向切面编程,在软件开发中比重最大的就是面向对象编程了
  • 在面向对象中有一个"类"的概念,其实它就是模板
  • 面向对象的三要素:继承 封装 多态
    • 继承:子类继承父类(公共类)
    • 封装: 数据的权限和保密, 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 ) 从设计到模式

  • 设计:设计原则
  • 模式:总结出来的模板,可效法的固定的东西
  • 设计和模式分开,从设计到模式

你可能感兴趣的:(Web,Full,Stack,Design,Pattern,设计模式,架构,面向对象,软件设计原则)