提到设计模式,对于初学者来说可能会有些陌生,不知道它到底是个什么东西,也不知道如何将设计模式运用到自己的代码中。那么,今天就带大家走进设计模式。
现有的设计模式一共有23种,根据他们的作用,大致可将他们分为三大类:
1. 创建型模式
2. 结构性模式
3. 行为性模式
通过分类的名字其实我们大概能够知道各分类的设计模式大概是什么作用了,但是今天我们先不讲具体的设计模式,为了让大家更好的理解设计模式的产生,我想先给大家讲讲面向对象开发的七大原则。这么来说,七大原则是23种设计模式产生的基础,设计模式正是因为实现了这些原则,才达到了代码复用、增加可维护性的目的。
值的注意的是,七大原则不是针对设计模式提出的原则,而是对面向对象开发时为了达到某些目的,对代码质量提出的规范。
开闭原则
开闭原则指的是,对扩展开放,对修改关闭。
什么意思呢?就是说面向对象开发中,开发原则允许我们在不对原有的代码进行修改的情况下对代码原有功能进行扩展。这句话听上去有点让人摸不着头脑,既然要扩展功能,我不能对原有代码进行修改的话怎么能达到扩展的目的呢?其实,这里就是告诉我们在开发的时候,使用接口或抽象类,这个在之后的设计模式讲解中会有体现。(不懂什么是接口和抽象类?请自行修炼面向对象编程)
单一职责原则
单一职责原则指的是,一个类应该只有一个发生变化的原因。也就是说每个类应该实现单一的职责。
里氏替换原则
里氏替换原则指的是,所有基类出现的地方,如果将其换位该基类的子类,代码也应该能够运行。
里氏代换原则联系到了面向对象编程的核心概念 -- 继承。而这也算是对开闭原则的补充。前面说了,开闭原则的实现基于接口和抽象类,将父类抽象化,而子类对父类进行具体的实现,由于里氏替换原则,我可以随时将抽象的父类替换为具体的子类(事实上,基类算是泛指抽象出规范的基础,所以除了类以外,接口也是符合里氏代换原则的)。
依赖倒转原则
依赖倒转原则指的是,面向接口编程,依赖于抽象而不是具体类。依赖倒转原则是实现开闭原则的基础。
我们怎么去理解面向接口编程呢?在面向对象开发中,我们会分析所有涉及的对象,并编写这些对象的类,并在之后的开发中创建这些类以实现某些功能。但其实在实际开发中,在类中方法具体的实现上,存在很多的未知数。比如我们在开发一个拨打电话的APP的时候,我们可能会编写一个App的类,之后我们会编写一个call()方法以实现该APP打电话的功能。问题来了,当前市面上有众多,不同厂商手机我们假定她拨打电话的实现方法不同(只是假设),我们怎么去编写具体实现的代码呢?可能有人会想到在方法内对手机厂商进行判断,然后在根据判断的结果执行不同的代码。
这样当然可以解决当前问题,但当又有新的厂商出现,我们要兼容新厂商时,问题又来了。我们不能直接修改原有代码,因为这样不符合开闭原则,怎么办呢?这里就是为什么说依赖倒转是开闭原则实现的基础的原因,我们一开始,对App类进行抽象,只规定其拥有call()功能。在代码编写上我们只调用XXX.call(),即只需要与抽象部分打交道,具体的实现由继承该类的子类去实现。由于里氏替换原则,我们可以随时通过各种方式将抽象部分替换为具体。这样编写的好处是,单个类的大小不会特别大,其次,如果我要进行扩展,只需要继承抽象类重新编写一个具体实现的子类即可。
可能会有点难理解,我写的也有点绕(说不定把我自己都绕进去了),大家可以先有个大概的概念,在之后我会详细给大家讲解面向接口编程。
接口隔离原则
接口隔离原则指的是,一个接口只应该是一个角色。这我个人感觉其实和单一职责原则有些类似,只是单一职责原则针对类,接口隔离原则针对接口。还有,一般来说,一个接口中的方法不应太多,一个最好。所以,接口中若有多个方法的时候,就应该考虑是否需要将其根据方法具体的职能分为多个接口。
迪米特法则
迪米特法则又被称为最少知道原则,即一个对象应该尽量少去了解其他对象。
按照迪米特法则来说,一个单独的类应该能够独立实现该类所要实现的功能,而不去依赖其他类(或者说尽量少的依赖)。关于这个法则,在后面的设计模式中会再详细的去说。
合成复用原则
合成复用原则,尽量使用合成 / 聚合的关系,而少使用继承。
当我们想要使用某一个类里面的变量或者方法时,我们第一想到的就是继承,将要使用的方法作为父类继承过来,这样就可以直接使用其拥有的方法与变量。但是,合成复用原则是不支持这样的做法的,其更推荐你将要使用的对象与当前对象产生合成 / 聚合关系,使其成为当前对象的一部分,继而使用其功能。
到这儿,就给大家讲完了面向对象编程的七大原则。希望大家能够仔细学习,因为这些原则是之后学习设计模式的基础,且这些原则也能使你以后的代码编写更规范。如果表示看不懂的话,可能,你需要学习一下面向对象编程的知识了。最后,欢迎大家在留言区留言进行提问交流和指正。
领取专属 10元无门槛券
私享最新 技术干货