非官方解读23种设计模式–总章
本章介绍设计模式的原则及解决的问题,以个人角度出发,瞎写的,如果有不同意见或者建议,可能也不是很能接受,但是不拒绝.接下来我们一点一点的学习,会往下推导23种设计模式,以及具体使用和场景.不官方,全瞎扯.
设计模式能干嘛
设计模式是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案.设计模式并不直接用来完成代码的编写,而是描述在各种不同情况下,要怎么解决问题的一种方案。面向对象设计模式通常以类别或对象来描述其中的关系和相互作用,但不涉及用来完成应用程序的特定类别或对象。设计模式能使不稳定依赖于相对稳定、具体依赖于相对抽象,避免会引起麻烦的紧耦合,以增强软件设计面对并适应变化的能力。
其实,设计模式更偏向一种思想,它的宗旨是为了降低代码耦合,增加扩张性,便于维护,便于解读.人们往往希望把一些抽象的东西用公式解读,而设计模式也是由此而来.设计模式不会减少我们的开发量,大多数情况下往往会增加我们的工作量.但是这样的目的无非是便于扩展以及刚刚说的几点.
设计模式几大原则
开闭原则(ocp)
设计模式总原则,其他原则其实也是相映成辉的.开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,而是要扩展原有代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类等,后面的具体设计中我们会提到这点。也是新增或者修改不影响原有功能使用
这就是讲,我们新的代码不能影响老的,不能顾头不顾腚.要做到新旧隔离.这也是代码健壮性的一个指标.我们应该禁止在迭代时去动之前的代码.不要去给自己找事情
单一职责
不要存在多于一个导致类变更的原因,也就是说每个类应该实现单一的职责,如若不然,就应该把类拆分。在类比较简单的情况下,方法较少时,可以下沉到方法,方法做到单一.但是一旦类过于复杂就应当进行拆分.单一职责可以更好的进行控制复杂性,可维护以及可读性.
类的职责应该单一,订单类就不要把仓储和付款这些处理搞进来,水只会越搅越浑.保证一个类干的是一件事或者一类事,不要把简单的东西揉在一起,那是灾难.比如找个女朋友,你不能让她当厨师用.你应该要根据行为或者抽象的对象进行规整,不相关的就让她离远点.
里氏替换
里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。也就是说子类不应该去重写父类的方法,父类中实现的方法应该是透明的,而我们如果去重写后就会更改了原有父类的逻辑.针对子类需要重写父类的方法这种情况,我们可以将父类中不需要被重写的方法抽象出来,建立一个基础类,让父类和子类进行继承.让他们处于同一级,而不是父子关系.如果要使用父类中的方法时,就采取依赖,聚合,组合等关系替代.
一个类具有了行为,如果我们继承了,那我们就不应该去改变父类的行为,因为作为儿子你能够扩展.你既然继承了你爹的东西,那么就用你爹的.如果你继承了你爹的又要去改变,那就不要这个爹了.重新找一个爹.有点话糙理不糙的感觉.其实也是说,我们应该保持父类的行为透明,我们继承就是要使用父类的行为,如果不满足了,那么我们就不要去继承了.设计模式中对继承的限制比较多,慎用
依赖倒转
面向接口编程,依赖于抽象而不依赖于具体。写代码时用到具体类时,不与具体类交互,而与具体类的上层接口交互。通过使用接口就可以多一个缓冲层,让我们后续如果有更改的时候或者扩展时就可以更容易维护.如果直接引用具体实现类,我们代码的耦合性就会很高.建立依赖关系可以通过 接口传入,构造器传入,setter传入三种方式.
在进行操作时,如方法参数或者我们注入了一个对象的时候,我们要使用接口或者抽象类实现,而不是指定具体的实现者,因为如果直接使用了实现者,那就是强耦合,虽然我们编程中不会感觉有什么不对,甚至还觉得自己有点牛逼,但是如果要进行扩展时,我们就只能修改具体实现类.如果中间有抽象类或者接口,我们进行扩展时范围就更大了,能做的更多.我们常用的地方比如Collection 就是,其中的很多操作都是基于接口,而不是具体的ArrayListy.
接口隔离
每个接口中不存在子类用不到却必须实现的方法,如果不然,就要将接口拆分。使用多个隔离的接口,比使用单个接口(多个接口方法集合到一个的接口)要好。保证类的干净.如果存在子类用不到的方法,可以通过接口拆分,拆分为更基础的接口.这样可以有选择的进行实现方法,避免无用方法的实现.这里也可以借鉴jdk中collection中的做法,定义抽象类,对于方法返回UnSupport 异常.这样我们可以选择性实现我们需要的方法.减少不需要方法的实现,在调用未实现方法时异常抛出.
这是指接口和实现方,我们如果实现了一个接口,那就要实现它的所有,如果有一些我们用不到怎么办,那岂不是白干了,虽然代码不多,但是你写哪了,后边的人动也不敢动,垃圾代码也是由此越来越多的.如果存在这种就应该再次抽象,将通用的提升一层.当然如果更为通用的也可以下沉.
迪米特法则
一个类对自己依赖的类知道的越少越好。也就是说无论被依赖的类多么复杂,都应该将逻辑封装在方法的内部,通过public方法提供给外部。这样当被依赖的类变化时,才能最小的影响该类。降低类和类之间的耦合关系,但不是完全没有.
我们在通过自己依赖的类进行操作时,里面的细节我们知道的越少越好,就像第三方框架,spring,mybatis之流,它们做到了很好的文档,我们只需要按照文档进行操作即可,不需要去弄清楚他的底层到底做了什么,怎么做的.我们只需要用我们要用的就行了.这样的好处是,我们不需要过多关注其他类的操作.其实这里面也有一个思想,那就是组件式开发,我们把所有名词抽象后形成了类,我们再把类的行为进行抽象然后提供操作方法,这样就形成了一个组件,我们用即可,不用关注它的内部.
合成复用
原则是尽量首先使用合成/聚合的方式,而不是使用继承。
那就是减少耦合了,因为继承毕竟太强了.用合成,聚合,关联就可以做到的事情不要去麻烦继承.
二十三种设计模式插眼
- 预留传送门,眼睛插在这了,能不能tp不知道
单例模式
工厂模式
建造者模式
原型模式
适配器模式(Adapter)
装饰器模式(Decorator)-转载
代理模式(Proxy)
外观模式(Facade)
桥接模式(Bridge)
组合模式(Composite)
享元模式(Flyweight)
本文借鉴尚硅谷Java设计模式,韩顺平图解java,传送门