设计原则是基本的工具,应用这些规则可以使代码更加灵活、更容易维护,更容易扩展。基本原则:封装变化Encapsulate what varies. 面向接口变成而不是实现 Code to an interface rather than to an implementation. 优先使用组合而非继承 Favor Composition Over Inheritan
什么是设计原则?
设计原则是基本的工具,应用这些规则可使你的代码更加灵活、更容易维护,更容易扩展。
基本原则
- 封装变化Encapsulate what varies.
- 面向接口变成而不是实现 Code to an interface rather than to an implementation.
- 优先使用组合而非继承 Favor Composition Over Inheritance
SRP: The single responsibility principle 单一职责
系统中的每个对象都应该只有一个单独的职责,而全部对象所关注的就是自身职责的完成。
Every object in your system should have a single responsibility ,and all the object s services should be focused on carrying out that single responsibility .
- 每个职责都是一个设计的变因,需求变化的时候,需求变化反映为类职责的变化。当你系统里面的对象都只有一个变化的缘由的时候,你就已经很好的遵循了SRP原则。
- 若是一个类承担的职责过多,就等于把这些职责耦合在了一块儿。一个职责的变化就可能削弱或者抑制这个类其它职责的能力。这种设计会致使脆弱的设计。当变化发生的时候,设计会遭到意想不到的破坏。
- SRP 让这个系统更容易管理维护,由于不是全部的问题都搅在一块儿。
- 内聚Cohesion 实际上是SRP原则的另一个名字.你写了高内聚的软件其实就是说你很好的应用了SRP原则。
- 怎么判断一个职责是否是一个对象的呢?你试着让这个对象本身来完成这个职责,好比:“书本身阅读内容”,阅读的职责显然不是书本身的。
- 仅当变化发生时,变化的轴线才具备实际的意义,若是没有征兆,那么应用SRP或者任何其它的原则都是不明智的。
DRY : Don't repeat yourself Principle
经过抽取公共部分放置在一个地方避免代码重复.
Avoid duplicate code by abstracting out things that are common and placing those thing in a single location .
- DRY 很简单,但倒是确保咱们代码容易维护和复用的关键。
- 你尽力避免重复代码候实际上在作一件什么事情呢?是在确保每个需求和功能在你的系统中只实现一次,不然就存在浪费!系统用例不存在交集,因此咱们的代码更不该该重复,从这个角度看DRY可就不仅是在说代码了。
- DRY 关注的是系统内的信息和行为都放在一个单一的,明显的位置。就像你能够猜到正则表达式在.net中的位置同样,由于合理因此能够猜到。
- DRY 原则:如何对系统职能进行良好的分割!职责清晰的界限必定程度上保证了代码的单一性。
OCP : Open-Close Principle开闭原则
类应该对修改关闭,对扩展打开;
Classes should be open for extension ,and closed for modification .
- OCP 关注的是灵活性,改动是经过增长代码进行的,而不是改动现有的代码;
- OCP的应用限定在可能会发生的变化上,经过建立抽象来隔离之后发生的同类变化
- OCP原则传递出来这样一个思想:一旦你写出来了能够工做的代码,就要努力保证这段代码一直能够工做。这能够说是一个底线。稍微提升一点要求,一旦咱们的代码质量到了一个水平,咱们要尽最大努力保证代码质量不回退。这样的要求使咱们面对一个问题的时候不会使用凑活的方法来解决,或者说是听任自流的方式来解决一个问题;好比代码添加了无数对特定数据的处理,特化的代码愈来愈多,代码意图开始含混不清,开始退化。
- OCP 背后的机制:封装和抽象;封闭是创建在抽象基础上的,使用抽象得到显示的封闭;继承是OCP最简单的例子。除了子类化和方法重载咱们还有一些更优雅的方法来实现好比组合;
怎样在不改变源代码(关闭修改)的状况下更改它的行为呢?答案就是抽象,OCP背后的机制就是抽象和多态
- 没有一个能够适应全部状况的贴切的模型!必定会有变化,不可能彻底封闭.对程序中的每个部分都肆意的抽象不是一个好主意,正确的作法是开发人员仅仅对频繁变化的部分作出抽象。拒毫不成熟的抽象和抽象自己同样重要。
- OCP是OOD不少说法的核心,若是这个原则有效应用,咱们就能够获更强的可维护性 可重用 灵活性 健壮性 LSP是OCP成为可能的主要原则之一
LSP: The Liskov substitution principle
子类必须可以替换基类。
Subtypes must be substitutable for their base types.
- LSP关注的是怎样良好的使用继承.
- 必需要清楚是使用一个Method仍是要扩展它,可是绝对不是改变它。
- LSP清晰的指出,OOD的IS-A关系是就行为方式而言,行为方式是能够进行合理假设的,是客户程序所依赖的。
- LSP让咱们得出一个重要的结论:一个模型若是孤立的看,并不具备真正意义的有效性。模型的有效性只能经过它的客户程序来表现。必须根据设计的使用者作出的合理假设来审视它。而假设是难以预测的,直到设计臭味出现的时候才处理它们。
- 对于LSP的违反也潜在的违反了OCP
DIP:依赖倒置原则
高层模块不该该依赖于底层模块 两者都应该依赖于抽象
抽象不该该依赖于细节 细节应该依赖于抽象
- 什么是高层模块?高层模块包含了应用程序中重要的策略选择和业务模型。这些高层模块使其所在的应用程序区别于其它。
- 若是高层模块依赖于底层模块,那么在不一样的上下文中重用高层模块就会变得十分困难。然而,若是高层模块独立于底层模块,那么高层模块就能够很是容易的被重用。该原则就是框架设计的核心原则。
- 这里的倒置不只仅是依赖关系的倒置也是接口全部权的倒置。应用了DIP咱们会发现每每是客户拥有抽象的接口,而服务者从这些抽象接口派生。
- 这就是著名的Hollywood原则:"Don't call us we'll call you."底层模块实现了在高层模块声明并被高层模块调用的接口。
- 经过倒置咱们建立了更灵活 更持久更容易改变的结构
- DIP的简单的启发规则:依赖于抽象;这是一个简单的陈述,该规则建议不该该依赖于具体的类,也就是说程序汇总全部的依赖都应该种植于抽象类或者接口。
- 若是一个类很稳定,那么依赖于它不会形成伤害。然而咱们本身的具体类大可能是不稳定的,经过把他们隐藏在抽象接口后面能够隔离不稳定性。
- 依赖倒置能够应用于任何存在一个类向另外一个类发送消息的地方
- 依赖倒置原则是实现许多面向对象技术多宣称的好处的基本底层机制,是面向对象的标志所在。
ISP:接口隔离原则
不该该强迫客户程序依赖它们不须要的使用的方法。
- 接口不是高内聚的,一个接口能够分红N组方法,那么这个接口就须要使用ISP处理一下。
- 接口的划分是由使用它的客户程序决定的,客户程序是分离的接口也应该是分离的。
- 一个接口中包含太多行为时候,致使它们的客户程序之间产生不正常的依赖关系,咱们要作的就是分离接口,实现解耦。
- 应用了ISP以后,客户程序看到的是多个内聚的接口。