面向对象设计原则笔记

Single responsibility principle 单一职责原则

原理

一个类应该仅仅只有一个被修改的理由,也就是一个类只有一个职责;而不是一种功能。

缺点

  1. 因为不同原因修改类的时候,也可能因为不相关的修改导致功能间的相互影响。
  2. 单个类承担的职责越多,意味着类的复杂度也就越高,维护成功也就越高。

如何解决

  1. 拆分大类为多个小类
  2. 将一些功能抽取为公共的函数

Open-closed principle 开放-关闭原则

原理

类应该对扩展开放,对修改封闭;应该可以在不修改某个类的前提下,扩展它的行为。

改造方法

使用类继承来改造代码

找到你类中会变动的部分,将其抽象成新的方法或者属性,最终允许新的子类来重写它以改变类似的行为。

使用组合与信赖注入来改造代码

将需要变化的内容,抽象为类,并将不同的原则实现不同的类,在调用主类进行操作的时间,不同的继承结果会让类有不同的变化,但是这种方案,并不会修改主类,因为接受的类型为变化的类的祖先,也就是保证的类的不变,但是传入的内容变化却是变的。

使用数据驱动思想来改造代码

数据驱动也就是将经常变化的东西完全以数据的方式抽离出来,当需求变动时,只改动数据,代码逻辑保持不变。

三种方案的区别

类继承与依赖注入方式的区别

两个原则都运用了继承来优化代码,第一个方案重点在于扩展类的行为,但是又保证父类的行为不变;第二种方案是将扩展行为的变量抽象出来,类本身的行为一直没有变化,主要都是接受抽象出来的类进行变化,保证可变量才能变。这种明显比第一种方案更为优越。但是理解和拆分也更有难度。

依赖注入与数据驱动方式的区别

依赖注入和数据驱动的两种改造方案非常相似,主要方案就是将变的内容抽离到类的外部,区别主要在于依赖注入主要是抽离类,通过类的变化来控制行为变化,而数据驱动抽离的是数据内容。

数据驱动的特点

与继承和依赖注入方式相比,数据驱动更简洁,不需地定义额外的类,但是同样也不缺点,也就是数据都是既定的内容,如果是传入的内容本身就是一种形态,数据的方案也就不可靠了。在使用中可以认为,如果是既定内容,可以简单的使用数据驱动来做,如果是某种类型,使用扩展类(依赖注入、类继承)的方式更好用。

Liskov Substitution Principle 里氏替换原则

特点

  1. 继承、多态与封装,属于面向对象编程的几大核心特征。里氏替换原则对继承有指导意义。
  2. 使用继承时,子类对象应该可以在程序中替代父类对象使用,而不破坏程序原本的功能。
  3. 尽量将可变的行为做为类的一个属性(可变),并提供方法可以修改这个行为。
  4. 需要让子类方法和父类方法返回同一类型的结果,支持同样的操作。或者更进一步,返回支持更多种操作的子类型结果也是可以授受的。
  5. 子类方法参数应该和父类方法同名方法完全一致,或者更为宽松。

Interface Segregation Principle 接口隔离原则

什么是接口

接口是模块间相互交流的抽象协议。

遵守的原则

  1. 客户(client)应该不依赖于它不使用的方法。
  2. 一个接口所提供的方法,应该就是使用方所需要的方法。而更多的接口方法意味着更高的实现成本,给实现方带来更多的出错机率。
  3. 让客户(调用方)来驱动协议设计。在有多余的依赖时,找出最小类,然后依据不同的依赖关系,继承出更小的类。

Dependency Inversion Principle 依赖倒置原则

特征

  1. 高层模块不应该依赖于低层模块,二者都应该依赖于抽象。
  2. 通过编写测试反向推动设计改进。
  3. 抽象解耦了高层模块和低层模块间的依赖关系,让代码更灵活。但抽象同时也带来了额外的编程与理解成本。而只有对代码中现在或者未来会发生变化的东西进行抽象,才能获得最大的利益。
Author
Tags
总结(3) Emacs(2) org mode(4) 年度清单(2) 读书清单(2) 电影清单(2) 电视清单(2) Python(3) 学习计划(1) 子弹笔记(1) 手帐体系(1) 时间管理(1) 时间使用效率(1) 形意拳(1) 知识管理(1) 简历(1) 技能水平(1) 生活(1) 减法生活(1) 阅读(1) 阅读分组(1) org(1) docx(1) markdown(2) cmder(1) 图床(1) jsdelivr(1) github(1) 安卓系统(1) 手动更新手机系统(1) post link(1) post path(1) hexo(2) hugo(2) GitHub Pages(1) travis(1) 自动部署博客(1) presentation(1) gcc(1) g++(1) 默认表格(1) 复杂表格(1) multimd table(1) google adsense(1) evil(1) surround(1) librime(2) emacs-rime(1) liberime(1) dot(1) graphviz(1) use-sub-superscripts(1) ditaa(1) Evil Multiple cursors(1) turn evil mode off(1) modifier keys(1) keymap(1) super(1) hyper(1) install Emacs(1) Mac OS(1) keybinds(1) clocktable(1) coding system(1) image library(1) keybind(1) spacemacs(1) org babel(1) homebrew(1) dd(1) diskutil(1) tmux(1) xcode(1) xcrun(1) node-gyp(1) tar(1) tree(1) pacman(1) plantuml(1) find(1) grep(2) du(1) apt-get(1) apt(1) regex(1) wildcard(1) zsh(1) gdb(1) lsof(1) netstat(1) rebase(2) workflow(1) 工作流(1) .gitignore(1) postbuffer(1) hung up(1) merge(1) cache(1) reset(1) Git(1) command(1) submodule(1) GitHub Pull Request(1) pr(1) Matplotlib(1) beautifusoup(1) 下载小说(1) SOLID(1) Leetcode(2) 透视表(1) read_excel()(1) pandas(1) conda(1) django(1) markdown-deux(1) mysql(1) oracle(1) 模糊查询(1) logging level(1) reflex(1) Field(1) Maven(1) Selenium(1) 下拉框(1) select into(1) insert into select(1) CAST(1) CONVERT(1) timestamp(1) concat(1) concat_ws(1) group_concat(1) union(1) grant privileges(1) 重置 root 密码(1) 报错 10060(1) 清理连接数(1) create user(1) set password(1) exists(1) in(1) markdown-it(1) emoji(1) tasks(1) valine(1) Code 504(1) Hugo(1) theme(1) substring(1) indexOf(1) RegExp(1) 定位节点(1) 正则匹配(1) async(1) 异步请求(1) css(2) layui(1) 滚动条(1) JavaScript(1)