设计模式(引言)
撰写于 2018-06-05 修改于 2018-06-13 分类 设计模式
面试的过程中,经常会问到设计模式这个东西,如果没有留心这方面的知识一定很懵,what?我没有用过啊?!有可能你真的没有用过,还有一种可能,你用过了,但是你没有留意,还有你留意了,但是不知道是啥东西。OK,先简单的总结一下,设计模式有多少种,23种!分为3大类:
- 创建型模式
- 工厂方法模式
- 抽象工厂模式
- 单例模式
- 建造者模式
- 原型模式
- 结构型模式
- 适配器模式
- 装饰器模式
- 代理模式
- 外观模式
- 桥接模式
- 组合模式
- 享元模式
- 行为型模式
- 策略模式
- 模板方法模式
- 观察者模式
- 迭代子模式
- 责任链模式
- 命令模式
- 备忘录模式
- 状态模式
- 访问者模式
- 中介者模式
- 解释器模式。
除了以上的23模式,还有另外两种:并发型模式和线程池模式。
如果你没有用过上面的任何一种,刚刚接触到这些设计模式,你可能会觉得怎么怪怪的,这么繁琐,我用其他的方法同样可以实现啊,感觉用处不大啊?有这样的疑问,很正常,如果你没有一定的代码量积累,或者没有做过大型工程,可能会有这样的困惑,没关系,先了解一下,等到用到的时候在回头想想,就会恍然大悟!当热这些设计模式不是凭空想象的,是遵循一些原则的。
- 开闭原则
OCP,对扩展开放,对修改封闭。也就是,在程序需要拓展的时候,不能去修改原有的代码,而是扩展原有的代码,实现一个热插播的效果。一句话概括,就是:为了程序的扩展性好,利于维护和升级 - 单一职责原则
也就是著名的SRP原则:单一职责原则就是指一个类或者模块应该有且只有一个改变的原因。简单来说,一个类应该是一组相关性很高的函数,数据的封装。例如MVC,就是这个原则的最好实践。 - 里氏替换原则
也就是LSP原则:任何基类出现的地方,子类一定可以出现。里氏替换原则是对开闭原则的补充。 - 依赖倒转原则
DIP:面向接口编程,依赖于抽象而不依赖于具体。写代码时,用到具体的类时,不与具体类交互,而与具体类的上层接口交互。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。
一个应用中的重要策略决定及业务模型正是在这些高层的模块中。也正是这些模型包含着应用的特性。但是,当这些模块依赖于低层模块时,低层模块的修改将会直接影响到它们,迫使它们也去改变。这种境况是荒谬的。应该是处于高层的模块去迫使那些低层的模块发生改变。应该是处于高层的模块优先于低层的模块。无论如何高层的模块也不应依赖于低层的模块。而且,我们想能够复用的是高层的模块。通过子程序库的形式,我们已经可以很好地复用低层的模块了。当高层的模块依赖于低层的模块时,这些高层模块就很难在不同的环境中复用。但是,当那些高层模块独立于低层模块时,它们就能很简单地被复用了。这正是位于框架设计的最核心之处的原则。 - 接口隔离原则:
ISP:使用多个隔离的接口,比使用单个接口摇号。降低类直接的耦合度。
使用多个专门的接口比使用单一的总接口要好。
一个类对另外一个类的依赖性应当是建立在最小的接口上的。
一个接口代表一个角色,不应当将不同的角色都交给一个接口。没有关系的接口合并在一起,形成一个臃肿的大接口,这是对角色和接口的污染。
“不应该强迫客户依赖于它们不用的方法。接口属于客户,不属于它所在的类层次结构。”这个说得很明白了,再通俗点说,不要强迫客户使用它们不用的方法,如果强迫用户使用它们不使用的方法,那么这些客户就会面临由于这些不使用的方法的改变所带来的改变。 - 迪米特法则(最少知道原则)
最少知道原则:一个实体应当尽量少的与其他实体时间发生相互作用,使得系统功能模块相对独立。 - 合成复用原则
CRP:尽量使用合成、聚合的方式,而不是使用继承。