设计模式见解

2019-04-18  本文已影响0人  lzp1234

设计模式

什么是设计模式?

设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。
本意是对具体功能代码得预先设计。比如基类、接口得设计。
但这里不仅限于此,也包含了实际编码过程中需要遵守得一些规则。
设计模式可以帮助我们编写质量更高得程序。

开闭原则(Open Close Principle)

原文:

"software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification"
这里有两种:

  1. 梅耶开闭原则
  1. 多态开闭原则
    A class is closed, since it may be compiled, stored in a library, baselined, and used by client classes. But it is also open, since any new class may use it as parent, adding new features. When a descendant class is defined, there is no need to change the original or to disturb its clients.
理解:

我们可以去扩展一个软件实体(类,模块,方法等)得功能,但是不应该改变原有功能。

  1. 梅耶开闭原则:
    如果要对一个类添加新功能,应该新建一个类继承它,而不是直接修改它。
  2. 多态开闭原则:
    使用抽象类,接口。

个人认为:
梅耶开闭原则指的是在产品上线以后,需要添加新的功能时。不能够去修改原有得类或方法。而是通过继承复用原有得基类,在此基础之上再增加新的功能。
在设计阶段时,多态开闭原则倡导使用抽象类,接口。这么做目的是实现多态,而多态则不用修改基类就可以实现新功能。
总的来说,开闭原则都指向一个方向:不变动原有代码,通过一系列手段增加新功能。当然,修改bug不算增加新功能。

开闭原则能带来什么好处?
不变动已经工作得代码。可以降低风险,降低代码审查得难度。

里氏替换原则(Liskov Substitution Principle )

原文:

What is wanted here is something like the following substitution property: If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T.

理解:

提及这个规则时,往往伴随着一句话:子类可以替换父类。

子类可以替换父类得前提是父类得功能,子类中都有,并且功能一样。

然而开闭原则得多态,比如重写父类方法(你都重写了,子类当然不能替换父类)。这似乎有些冲突。

这里需要提一个概念。区分开“可以实例化得类”“抽象类、接口”

多态开闭原则是针对抽象类和接口得,并不是指所有的类。梅耶开闭原则更多得是指复用父类代码产生新类,而不是重写。

里氏替换原则针对得是继承于可以实例化得父类。
对于可以实例化得父类,遵守里氏替换原则就是:不重写父类已经拥有具体实现得方法

所以开闭原则和里氏替换原则并不冲突。合起来就是,开闭原则不提倡修改父类来提供新功能,里氏替换原则不提倡重写父类已经拥有具体实现得方法。

里氏替换原则能带来什么好处?
首先要清楚得一点就是,子类可以替换父类,不是说我们要用父类时去使用子类。这里是对代码得一种约束。
换个角度去论证,你需要去重写父类方法时,为什么继承于可以实例化得类而不是抽象类呢?
可以实例化得类是用来做事情得,是用来代码复用得。不是拿来当抽象类使用。

以上都是从某一角度出发得论证,意在理解。
从狭义得论证再回到广义就是:子类可以替换父类

单一职责原则(Single Responsibility Principle)

原文:

There should never be more than one reason for a class to change.

理解:

不要让一个类乱七八糟得做了所有事情。
拓展到方法上也是如此。

好处:
职责明确,可读性高,易于维护

依赖倒置原则(Dependence Inversion Principle)

原文:
  1. High level modules should not depend upon low level modules.
  2. Both should depend upon abstractions.
  3. Abstractions should not depend upon details. Details should depend upon abstractions.
理解:
  1. 高层模块不应该依赖底层模块。
  2. 两者都应该依赖其抽象。
  3. 抽象不应该依赖细节,细节应该依赖抽象。

个人理解:

  1. 面向对象替代面向过程
  2. 不同职责类之间不相互依赖,尽可能使用抽象类、接口。

举例:
面向对象得实现男人跳,女人跳。

一种实现方式:
男人类,女人类。分别实现跳方法。
控制类中,男人跳方法:实例化男人类,调用方法。
控制类中,女人跳方法:实例化女人类,调用方法。
执行时,实例控制类,调用男人跳方法,女人跳方法。

另外一种实现方式:
接口类,定义跳方法。
男人类继承接口类,实现跳方法。
女人类继承接口类,实现跳方法。
控制类定义跳方法,参数为接口类。
执行时,实例控制类,传入男人类、女人类,调用统一得跳方法。

这么看来,似乎第二种方法更复杂了。然而第二种才符合依赖倒置原则。
为什么呢?

此时世界上出现了新人种--矮人。那我得程序中需要加上矮人跳。

第一种方案情况下:
增加矮人类,实现跳方法。
控制类中,矮人跳方法:实例化矮人类,调用方法。
执行时,实例控制类,调用矮人跳方法。

而第二种方案情况下:
增加矮人类继承接口,实现跳方法
执行时,实例控制类,传入矮人类,调用统一得跳方法。

这两种方案得不同点在于,第二种方案在面对新的需求时无需改动控制类。而第一种方案则需要具体得修改控制类。在扩展性上第二种方案远胜于第一种方案。

依赖倒置,个人理解为:模块之间得松耦合,不同职责类之间通过接口、抽象类解耦。

接口隔离原则(Interface Segregation Principle)

原文:
  1. Clients should not be forced to depend upon interfaces that they don`t use.
  2. The dependency of one class to another one should depend on the smallest possible.
理解:
  1. 客户端不应该依赖它不需要的接口。
  2. 类间的依赖关系应该建立在最小的接口上。

个人更倾向于理解为 接口分离原则,强调一种细分得感觉。
类在使用接口时,不应当去被迫得实现类不需要得方法。也就是接口中定义得方法要尽可能得精简,不应当出现冗余得情况,否则就需重新设计接口,比如接口得拆分,哪怕一个接口拆的只剩一个方法。

迪米特法则(Law of Demeter)

原文:
  1. Each unit should have only limited knowledge about other units: only units "closely" related to the current unit.
  2. Each unit should only talk to its friends; don't talk to strangers.
  3. Only talk to your immediate friends.
理解:

引用百度的一段话,很直白的一段话。
迪米特法则(Law of Demeter)又叫作最少知识原则(Least Knowledge Principle 简写LKP)

迪米特法则的初衷在于降低类之间的耦合。由于每个类尽量减少对其他类的依赖,因此,很容易使得系统的功能模块功能独立,相互之间不存在(或很少有)依赖关系。

迪米特法则不希望类之间建立直接的联系。如果真的有需要建立联系,也希望能通过它的友元类来转达。因此,应用迪米特法则有可能造成的一个后果就是:系统中存在大量的中介类,这些类之所以存在完全是为了传递类之间的相互调用关系——这在一定程度上增加了系统的复杂度。

狭义的迪米特法则的缺点:
在系统里造出大量的小方法,这些方法仅仅是传递间接的调用,与系统的业务逻辑无关。
遵循类之间的迪米特法则会是一个系统的局部设计简化,因为每一个局部都不会和远距离的对象有直接的关联。但是,这也会造成系统的不同模块之间的通信效率降低,也会使系统的不同模块之间不容易协调。

广义的迪米特法则在类的设计上的体现:
1. 优先考虑将一个类设置成不变类。
2. 尽量降低一个类的访问权限。
3. 谨慎使用Serializable。
4. 尽量降低成员的访问权限。

写在最后

这六大原则,首字母可以组成一个单词 SOLID(稳定)。
S: Single Responsibility Principle:单一职责原则
O:Open Closed Principle:开闭原则
L: Liskov Substitution Principle:里氏替换原则, Law of Demeter:迪米特法则
I: Interface Segregation Principle:接口隔离原则
D:Dependence Inversion Principle:依赖倒置原则

上一篇 下一篇

猜你喜欢

热点阅读