现在有许多设计原则,但是最基本的,就是SOLID(缩写),这五项原则。
S = 单一责任原则
O = 开闭原则
L = Liscov替换原则
I = 接口隔离原则
D = 依赖倒置原则
1.单一责任原则(SRP 原则):
它的意思是:“如果你可以在一个设备中实现所有的功能,你却不能这样做”。为什么呢?因为从长远来看它增加了很多的可管理性问题。
从面向对象角度解释是:"导致类变化的因素永远不要多于一个。"或者换行个说法:"一个类有且只有一个职责"。
如果有多于一个原因会导致你的类改变(或者它的职责多余一个),你就需要根据其职责把这个类拆分为多个类。
为什么拆分很重要的?
那是因为:
- 每个职责都是轴向变化;
- 如果类包含多个职责,代码会变得耦合;
设计规则如下:
“软件实体(类,模块,函数等)应该对扩展开放,对修改关闭。”
这意味着在最基本的层面上,你可以扩展一个类的行为,而无需修改。这就像我能够穿上衣服,而对我的身体不做任何改变。
扩展开放意味着模块/类的行为可以被扩展,那么当需求变化时我们可以用各种各样的方法制定功能来满足需求变更或者新需求
你要对系统的核心业务进行抽象, 如果你抽象化做的比较好, 很可能, 在扩展功能的时候它们不必做任何改变 (比如Server就是一个抽象的概念). 你所定义的抽象的实现 (比如, IIS服务器 实现了 Server) 和 抽象的代码 (Server) 要尽可能的多. 这样在客户端代码中不需要做任何修改就会允许你定义一个新的实现(比如, ApacheServer) .
3.里氏替换原则:(多态性)LSP原则
原则描述了:
"子类型必须能够替换它们的基类."
或者, 换句话说:
"使用基类引用的函数必须能够使用派生类而无须了解派生类."
在基本的面向对象原则中, "继承" 通常被描述成 "is a" 的关系. 如果一个 "开发者" 是"软件专业人员", 那么 "开发者" 类 应该 继承 "软件开发人员" 类. 这样的 "Is a" 关系 在类设计阶段非常重要, 但是这也很容易让设计者得意忘形从而以一个糟糕的继承设计告终.
"里氏替换原则" 仅仅是一种确保继承被正确使用的手段.
- 如果不遵循 LSP原则,类继承就会混乱。如果子类实例被作为参数传递给方法,后果难以预测。
- 如果不遵循 LSP原则,基于父类编写的单元测试代码将无法成功运行子类。
4.接口隔离原则:
“用户不应该被迫依赖他们不使用的接口。”假如你有一些类, - 你通过接口暴露了类的功能,这样外部就能够知道类中可用的功能,客户端也可以根据接口来设计。当然那,如果接口太大,或是暴露的方法太多,从外部看也会很混乱。接口包含的方法太多也会降低可复用性, 这种包含无用方法的”胖接口“无疑会增加类的耦合。
- 这还会引起其他的问题。如果一个类视图实现接口,它需要实现接口中所有的方法,哪怕一点都用不到。所以,这样会增加系统复杂度,降低系统可维护性和稳定性。接口隔离原则确保接口实现自己的职责,且清晰明确,易于理解,具有可复用性。
5.依赖倒置原则:(关键是抽象)
“高层次的模块不应该依赖于低层次的模块,而是,都应该依赖于抽象。”
如果代码不遵循依赖倒置,就有下面的风险:
- 使用低层级类会破环高层级代码;
- 当低层级的类变化时,需要太多时间和代价来修改高层级代码;
- 代码可复用性不高
除 SOLID 原则外还有很多别的面向对象原则。比如:
- “组合替代继承”:是说“用组合比用继承好”;
- “笛米特法则”:是说“类对其它类知道的越少越好”;
- “共同封闭原则”:是说“相关类应该一起打包”;
- “稳定抽象原则”:这是说"类越稳定,就越应该是抽象类";