设计模式六大原则
设计模式
面向对象语言开发过程中,遇到种种的场景和问题,提出的解决方案和思路,沉淀下来就是设计模式
设计模式是解决具体问题的套路
设计模式六大原则
面向对象语言开发中,推荐一些指导性原则;
没有明确的招数,而且经常会被忽视/违背;
前辈总结,也是为了站在前辈的肩膀上;
单一职责原则(Single Responsibility Principle)
单一职责原则:类T负责两个不同的职责:职责P1,职责P2。当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障。
原则就是一个类只负责一件事。
面向对象语言开发,类是一个基本单位,单一职责原则就是封装的粒度。
原因:
写分支判断,然后执行了不同的逻辑,其实就是违背了单一职责原则,但是功能是可以实现的
-
解决方法就是:
拆分父类+子类
每个类很简单,简单以为这稳定,意味着强大 -
缺点:
拆分后会增加代码量的增加
类多了,使用成本变高(理解成本) -
究竟该什么时候使用单一职责原则
如果类型足够简单,方法够少,是可以在类级别违背单一职责原则
如果类型复杂,方法多了,建议遵循单一职责原则 -
方法级别的单一职责原则:
一个方法只负责一件事(职责拆分小方法,分支逻辑分析)
-
类级别的单一职责原则:
一个类只负责一件事 -
类库级别的单一职责原则:
一个类库应该职责清晰 -
项目级别的单一职责原则:
一个项目应该职责清晰(客户端/管理后台/后台服务/定时任务/分布式引擎) -
系统级别的单一职责原则:
为通用功能拆分系统(IP定位/日志/在线统计)
里氏替换原则(Liskov Substiution Principle)
任何使用基类的地方,都可以透明的使用其子类
继承、多态
继承:子类拥有父类的一切属性和行为,任何父类出现的地方,都可以用子类来代替
继承+透明(安全,不会出现行为不一致)
- 父类有的子类必须有
如果出现了子类没有的东西,那么就应该断掉继承。如果硬要这么干,就再加一个父类,父类只包含都有的东西 - 子类可以有自己的属性和行为
子类出现的地方,父类不一定能代替
白马非马 - 父类实现的东西,子类就不要再写了(就是不要new隐藏)
有时候会出现意想不到的情况,把父类换成子类后,行为不一致
如果想修改父类的行为,通过abstract/virtual
声明属性,字段,变量,尽量声明成父类
依赖倒置原则(Dependence Inversion Principle)
高层模块不应该依赖于底层模块,二者应该通过抽象依赖,而不是依赖细节
抽象:接口/抽象类–可以包含没有实现的元素
细节:普通类–一切都是确定的
面向抽象编程:尽量的使用抽象,80%的设计模式都跟抽象有关
属性、字段、方法、参数、返回值 尽量都是抽象
接口隔离原则(Interface Segregation Principle)
客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小接口上
-
接口到底该如何定义?
既不能是大而全,会强迫实现没有的东西,也会依赖自己不需要的东西也不能一个方法一个接口,这样面向抽象也没有什么意义的
按照共的密不可分来定义接口,而且应该是动态的,随着业务的发展会有变化的但是在设计的时候要提前定量,避免抽象的变化, 没有标准答案,随着业务和产品调整
接口合并 Map–定位/搜素/导航 这种属于固定步骤,业务细节,尽量的内聚,在接口也不要暴露太多
迪米特法则(Law Of Demeter)
迪米特法则又叫 最少知道原则:
一个对象应该对其他对象抱持最少的了解。
只与直接的朋友通信。
面向对象语言–万物皆对象–类和类之间交互才能产生功能–这不就是耦合了吗。
高类聚低耦合
类与类之间的关系:
纵向:继承父类;实现接口 (最密切)
横向:聚合>组合> 关联>依赖(出现再方法内部)
- 迪米特法则:降低类与类之间的耦合
- 只与直接的朋友通信,就是要尽量避免依赖更多类型
- 基类库(BCL–框架内置类)的类型除外
- 迪米特,也会增加一些成本
- 去掉内部依赖
- 降低访问修饰符权限
- 依赖别人更少,让别人了解更少
开闭原则(Open Closed Principle)
对扩展开放,对修改关闭
修改:修改现有代码(类)
扩展:增加代码(类)
面向对象语言是一种静态语言,最害怕变化,会波及很多东西,全面测试
最理想就是新增类,对原有代码没有改动,原有的代码才是可信的
开闭原则只是一个目标,并没有任何的手段,也被称之为总则
其他5个原则的建议,就是为了更好的做到OCP
开闭原则也是面向对象语言开发一个中级目标
总结
设计模式的六大原则事实上项目很难全部遵循,更多的时候会有一些侧重性
设计模式的六大原则要能灵活运用,离不开时间的锤炼和思考,把这个真的给融到骨子里面去了,设计确实会不一样