《设计模式修炼真经》01 — OOP三大特性和六大原则

36 篇文章 0 订阅
16 篇文章 2 订阅

OOP简介

OOP也就是我们常说的面向对象编程(Object Oriented Programming,OOP);

面向对象程序设计方法是尽可能模拟人类的思维方式,使得软件的开发方法与过程尽可能接近人类认识世界、解决现实问题的方法和过程,也即使得描述问题的问题空间与问题的解决方案空间在结构上尽可能一致,把客观世界中的实体抽象为问题域中的对象。

面向对象程序设计以对象为核心,该方法认为程序由一系列对象组成。类是对现实世界的抽象,包括表示静态属性的数据和对数据的操作,对象是类的实例化。对象间通过消息传递相互通信,来模拟现实世界中不同实体间的联系。在面向对象的程序设计中,对象是组成程序的基本模块。

OOP=对象+类+继承+多态+消息,其中核心概念是类和对象


OOP三大特征

面向对象编程的三大特性是封装性继承性多态性

  1. 封装性:封装是指将一个计算机系统中的数据以及与这个数据相关的一切操作语言组装到一起,一并封装在一个有机的实体中,把它们封装在一个“模块”中,也就是一个类中,为软件结构的相关部件所具有的模块性提供良好的基础。
  2. 继承性:是面向对象技术中的另外一个重要特点,其主要指的是两种或者两种以上的类之间的联系与区别。继承,顾名思义,是后者延续前者的某些方面的特点,而在面向对象技术则是指一个对象针对于另一个对象的某些独有的特点、能力进行复制或者延续。
  3. 多态性:从宏观的角度来讲,多态性是指在面向对象技术中,当不同的多个对象同时接收到同一个完全相同的消息之后,所表现出来的动作是各不相同的,具有多种形态;

OOP设计原则

1、单一职责原则(SRP)

定义:就一个类而言,应该仅有一个引起它变化的原因

从这句定义我们很难理解它的含义,通俗讲就是我们不要让一个类承担过多的职责。如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到破坏。
单一职责原则是最简单的,也是最难达到的;
如果我们严格遵守单一职责原则,那么会导致我们的类非常多,通常情况下我们会做一些取舍,尽量做到让一个类的职责单一;
同样的,单一职责原则也适用于接口和方法,这样做不仅开发简单,后期维护也很轻松;
所以,对于单一职责,我们一般的做法是接口和方法遵守单一职责原则,类尽量做到


2、开放封闭原则(ASD)

定义:类、模块、函数等等等应该是可以拓展的,但是不可修改

开放封闭有两个含义,一个是对于拓展是开放的,另一个是对于修改是封闭的。对于开发来说需求肯定是要变化的,但是新需求一来,我们就要把类重新改一遍这显然是令人头疼的,所以我们设计程序时面对需求的改变要尽可能的保证相对的稳定,尽量用新代码实现拓展来修改需求,而不是通过修改原有的代码来实现。

假设我们要实现一个列表,一开始只有查询的功能,如果产品又要增加添加功能,过几天又要增加删除功能,大多数人的做法是写个方法然后通过传入不同的值来控制方法来实现不同的功能,但是如果又要新增功能我们还得修改我们的方法。用开发封闭原则解决就是增加一个抽象的功能类,让增加和删除和查询的作为这个抽象功能类的子类,这样如果我们再添加功能,你会发现我们不需要修改原有的类,只需要添加一个功能类的子类实现功能类的方法就可以了。

在六大原则中,开闭原则处于领袖地位,是总纲领,其他五个原则可以看成是实现开闭原则的途径;


3、里氏替换原则(LSP)

定义:所有引用基类(父类)的地方必须能透明地使用其子类的对象

里氏代换原则告诉我们,在软件中将一个基类对象替换成它的子类对象,程序将不会产生任何错误和异常,反过来则不成立,如果一个软件实体使用的是一个子类对象的话,那么它不一定能够使用基类对象。

里氏代换原则是实现开闭原则的重要方式之一,由于使用基类对象的地方都可以使用子类对象,因此在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。

在使用里氏代换原则时需要注意如下几个问题:

  • 子类的所有方法必须在父类中声明,或子类必须实现父类中声明的所有方法。根据里氏代换原则,为了保证系统的扩展性,在程序中通常使用父类来进行定义,如果一个方法只存在子类中,在父类中不提供相应的声明,则无法在以父类定义的对象中使用该方法。
  • 如果子类覆写或者实现父类方法,则必须保证参数范围相同或者更宽松(比如,父类中参数是HashMap类型,子类覆写时参数类型可以为HashMap或者更宽松的Map);子类覆写或者实现父类方法时,返回结果应该更小(比如,父类返回T,子类返回S,则要求S范围小于T)
  • 我们在运用里氏代换原则时,尽量把父类设计为抽象类或者接口,让子类继承父类或实现父接口,并实现在父类中声明的方法,运行时,子类实例替换父类实例,我们可以很方便地扩展系统的功能,同时无须修改原有子类的代码,增加新的功能可以通过增加一个新的子类来实现。里氏代换原则是开闭原则的具体实现手段之一。
  • Java语言中,在编译阶段,Java编译器会检查一个程序是否符合里氏代换原则,这是一个与实现无关的、纯语法意义上的检查,但Java编译器的检查是有局限的。

4、依赖倒置原则(DIP)

定义:高层模块不应该依赖低层模块,两个都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象

在Java中,抽象就是指接口或者抽象类,两者都是不能直接被实例化的;细节就是实现类,实现接口或者继承抽象类而产生的就是细节,也就是可以加上一个关键字new产生的对象。高层模块就是调用端,低层模块就是具体实现类。

依赖倒置原则在Java中的表现就是:模块间通过抽象发生关系,实现类之间不发生直接依赖关系,其依赖关系是通过接口或者抽象类产生的。如果类与类直接依赖细节,那么就会直接耦合,那么当修改时,就会同时修改依赖者代码,这样限制了可扩展性。

依赖倒置原则,总结起来就是面向接口编程,具体可以遵循如下规范:

  • 每个类尽量都有接口或抽象类,或者抽象类和接口两者都具备;
  • 变量的表明类型尽量是接口或者抽象类;
  • 任何类都不应该从具体类派生;
  • 尽量不要覆写基类的方法;
  • 要结合里氏替换原则使用;

5、迪米特原则(LOD)

定义:一个软件实体应当尽可能少地与其他实体发生相互作用

也称为最少知识原则。如果一个系统符合迪米特法则,那么当其中某一个模块发生修改时,就会尽量少地影响其他模块,扩展会相对容易,这是对软件实体之间通信的限制,迪米特法则要求限制软件实体之间通信的宽度和深度。迪米特法则可降低系统的耦合度,使类与类之间保持松散的耦合关系。

迪米特法则要求我们在设计系统时,应该尽量减少对象之间的交互,如果两个对象之间不必彼此直接通信,那么这两个对象就不应当发生任何直接的相互作用,如果其中的一个对象需要调用另一个对象的某一个方法的话,可以通过第三者转发这个调用。简言之,就是通过引入一个合理的第三者来降低现有对象之间的耦合度。

在将迪米特法则运用到系统设计中时,要注意下面的几点:

  • 在类的划分上,应当尽量创建松耦合的类,类之间的耦合度越低,就越有利于复用,一个处在松耦合中的类一旦被修改,不会对关联的类造成太大波及;
  • 在类的结构设计上,每一个类都应当尽量降低其成员变量和成员函数的访问权限;
  • 在类的设计上,只要有可能,一个类型应当设计成不变类;
  • 在对其他类的引用上,一个对象对其他对象的引用应当降到最低。

6、接口隔离原则(ISP)

定义:一个类对另一个类的依赖应该建立在最小的接口上

建立单一接口,不要建立庞大臃肿的接口,尽量细化接口,接口中的方法尽量少。也就是说,我们要为各个类建立专用的接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。

采用接口隔离原则对接口进行约束时,要注意以下几点:

  • 接口尽量小,但是要有限度。对接口进行细化可以提高程序设计灵活性,但是如果过小,则会造成接口数量过多,使设计复杂化。所以一定要适度。
  • 为依赖接口的类定制服务,只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来。只有专注地为一个模块提供定制服务,才能建立最小的依赖关系。
  • 提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。

接口隔离原则和单一职责原则表达的意思相同,但是侧重点不同,单一职责原则要求类和接口的职责要单一,侧重职责的划分,是业务逻辑上的划分,接口隔离原则是要求接口的方法尽量少;

六大原则首字母合起来为SOLLID(solid),只有牢牢掌握这六大原则,才能写出健壮的代码;

参考文章

设计六大原则

本文是《超越设计模式》系列的开篇,也是最抽象的理论总结,这也是可以反复读反复品味的一篇,同学们可以结合日常开发不断地总结,不断地加深对OOP三大特性和六大原则的理解,相信终有一天能够超越设计模式,达到无招胜有招的境界!



我的视频课
下面是我录制的一些视频课,欢迎大家围观~
《设计模式修炼真经》
设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结,代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。

本套课程深入介绍了经典的23种设计模式,并加入了自己的感悟,希望大家能够彻底掌握设计模式,写出最好的代码,达到无招胜有招的境界,最终超越这23种设计模式。

《彻底搞定JVM》
JVM是Java中重要的也是较难理解的内容;
面试者对JVM的了解程度某种程度上反映了面试者技术深度,所以JVM也是面试时经常考察的内容;
本课程从JVM运行流程、数据运行时区域组成部分、类加载机制、垃圾回收机制、内存模型、常见面试题讲解等角度出发,帮你彻底搞定JVM,拿下心仪Offer;

《Android性能优化参考》
本课程包含了Android中的App启动优化、UI优化、内存优化、图片优化、耗电量等常见的性能优化场景,通过学习此课程,你将对整个Android性能优化体系有清晰的认识。

性能优化作为Android高级开发的必备技能,也是大厂面试必考的题目,是体现一个人技术深度最好的试金石。

《面试之排序算法》
排序算法是我们面试被问到最多的基础算法,本课程详细介绍了七种排序算法,包括插入排序、选择排序、冒泡排序、谢尔排序、快速排序、堆积排序和二路并归排序。每种算法都详细介绍了核心思想、详细步骤、时间复杂度和代码实现,希望帮助大家深入理解排序算法,搞定面试!

《Android HyBrid App开发实战》
本课程为Android HyBrid App开发实战课程,由浅入深,从三种App的历史和特点开始,介绍了Android WebView的使用、Java和JS交互的原生方式、著名的WebView安全漏洞、JSBridge的原理和使用,最后通过一个网上商城的实战综合全部内容,让同学们掌握并深入理解Android HyBrid App开发。

《AI导论》
介绍人工智能AI的诞生历史和到现在为止的不同发展阶段;介绍了AI领域中常见的名词概念和其关系,包括机器学习、深度学习、神经网络结构搜索 NAS、生成对抗网络 GAN等;最后对AI发展做出展望。
本课程属于导论课程,旨在帮助同学们从宏观层面把握AI,建立AI的知识体系。

《Java注解精讲》
本课程详细介绍了Java中的注解机制,包括注解的定义和分类,注解的使用和自定义,注解的源码和架构分析;
本课程语言简单凝练,视频短小精悍,让你一次彻底搞懂Java注解!

《Java反射精讲》
反射是Java中重要的也是较难理解的内容;
本课程从反射的定义、作用、原理和使用出发,全方位帮你彻底搞定反射;


您的点赞是我前进的动力~

在这里插入图片描述
给作者买瓶咖啡提提神~


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不死鸟JGC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值