概念

面向过程编程OPP:Procedure Oriented Programming,是一种以事物为中心的编程思想。主要关注“怎么做”,即完成任务的具体细节。

面向对象编程OOP:Object Oriented Programming,是一种以对象为基础的编程思想。主要关注“谁来做”,即完成任务的对象。

面向切面编程AOP:Aspect Oriented Programming,基于OOP延伸出来的编程思想。主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。

每种编程思想都有各自的优点,它们适用在不同的情况下:面向过程性能很高,面向对象比较易于管理和维护,面向切面使软件变得更灵活。

新的编程范式,并不一定完全各方面都优于旧的编程范式,它们只是在某一特定领域或特殊场景下有着独到的优势。

编程范式只有适合不适合项目特性,没有绝对的好坏。

OPP和OOP

面向过程是最为实际的一种思考方式,就算是面向对象的方法也是含有面向过程的思想。可以说面向过程是一种基础的方法。它考虑的是实际地实现。一般的面向过程是从上往下步步求精,所以面向过程最重要的是模块化的思想方法。当程序规模不是很大时,面向过程的方法还会体现出一种优势。因为程序的流程很清楚,按着模块与函数的方法可以很好的组织。

面向对象是基于对象概念,以对象为中心,以类和继承为构造机制,来认识、理解、刻画客观世界和设计、构建相应的软件系统。类和继承是是适应人们一般思维方式的描述范式。方法是允许作用于该类对象上的各种操作。这种对象、类、消息和方法的程序设计范式的基本点在于对象的封装性和类的继承性。通过封装能将对象的定义和对象的实现分开,通过继承能体现类与类之间的关系,以及由此带来的动态联编和实体的多态性。

举个栗子:

比如完成“吃饭”这个任务。

面向过程的写法,需要封装一个eat()函数:

如果是狗吃屎,则eat(狗,屎);

如果是人吃肉,则eat(人,肉);

eat是人和狗共用的吃饭本能。

那如果之后要处理猫吃鱼、鱼吃虾、奥特曼吃小怪兽呢?eat函数中就会存在大量的if…else的判断,这段代码,无疑是很恶心的。

如果是面向对象思想,如何来解决这个问题呢?

我们发现,狗、人、猫、鱼、奥特曼,都有一个“吃”的共性。我们抽象出每个受体的类,然后继承,这样都具有“吃”的方法。

当我们想要执行狗吃屎时,那就“狗->eat(屎)”,这样,我们从面向过程维护eat()的焦点,转移到了面向对象维护角色的焦点上来。我们只需要维护好不同的角色(类)就好了,并且狗的eat不会影响到猫的eat,猫的eat也不会影响到人的eat。

所以,oop思想非常贴近软件工程高内聚的思想:自己管好自己的东西,自己做好自己的事情。

大多数支持面向对象的语言,同时也支持面向过程,不论是JAVA、PHP,还是JS,它们都还无法完全面向对象,因为面向过程是必然的,面向过程代表着必要的程序流程,调动对象进行组合或对象内部能力的实现,都一定会存在“过程”,它最终还是需要通过拆分步骤来指导最具体的执行细节。

在此,我们也能得到一些感悟,许多事情并非完全非黑即白,非OOP就必然是OPP,特别是思想层面的东西,它们呈现出互相结合的形态,从OPP到OOP,这是一个思想进步的过程。

AOP

面向切面编程主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。

那么,AOP如何体现?

这里可以联想一下laravel的中间件、javaweb的拦截器、vue的Decorator…它们都是AOP思想的实践。装饰器模式、代理模式,它们也是基于AOP思想的设计模式。

AOP思想,指导我们通过找到平整切面的形式,插入新的代码,使新插入的代码对切面上下原有流程的伤害降到最低。

举个栗子:

我们拿laravel中间件做什么?

权限、日志、请求过滤、请求频率限制、csrf过滤……

我们知道,中间件对于controller的业务逻辑,不会有任何伤害。

如果没有这个切面,我们想要记录请求日志,可能需要在每个controller的具体方法中写日志记录的代码,或者调用日志记录的函数、方法。

这会使一段记录日志的代码,或调用记录日志的调用语句出现在许多controller中,这与controller原本要关注的逻辑无关,使controller职责不单一,提高维护成本。

当然,我们可能会写一个父类,让许多controller来继承这个父类,然后统一在父类的__construct方法中记录日志,以此来解决耦合问题。

但实际上,这个父类的construct方法,不正是一个切面吗?它在原有流程中截取了一个切面,在切面中植入代码,以达到承上启下的作用,并且不对上下文产生伤害。

从这个例子中,我们也能得出另外一个思考:AOP指导我们寻找切面,但找到合适的切面,也尤为重要。就像上文,父类构造函数的切面和中间件的切面比起来,显然中间件这个切面更利于维护,你可以灵活选择中间件,但你无法灵活选择父类,因为决定你的controller继承什么父类的,不是切面中的代码,而是controller本身处理什么逻辑。

许多项目,OPP、OOP、AOP是同时存在的,它们是编程范式,是一种指导编程的思想,并非不能互相配合。

本文从宏观角度讲解三种编程思想的异同点,旨在引领大家打个样。具体到每个编程思想,其实还有很多深究的点,比如AOP思想,贯穿在很多设计模式中,比如代理模式、装饰器模式、职责链模式……;学无止境啊,每天成长一点,终究不会错的。

理解面向过程(OPP)、面向对象(OOP)、面向切面(AOP)的更多相关文章

  1. 【java初学者】理解,从面向过程 到 面向对象,面向接口,面向切面

    http://blog.csdn.net/ssh159/article/details/52516986

  2. 面向过程 vs 面向对象

    从网上摘录了一些面向过程vs.面向对象的分析,先简单记录如下,稍后会继续整理. 为什么会出现面向对象分析方法? 因为现实世界太复杂多变,面向过程的分析方法无法实现. 面向过程 采用面向过程必须了解整个 ...

  3. python 面向过程和面向对象比较

    面向过程 VS 面向对象 面向过程的程序设计:核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么......面向过程的设计就好比精心设计好一条流水线,是一种机械式的思维方式. 优点是:复杂度 ...

  4. C语言学习系列(二)面向过程和面向对象

    一.基本定义 (一).面向过程(procedure oriented programming POP) 面向过程是分析解决问题的步骤,然后用函数把这些步骤一步一步的实现,然后在使用的时候一一调用则可. ...

  5. 【JAVA】笔记(2)---面向过程与面向对象;类,对象;实例变量,引用;构造方法;

    面向过程与面向对象: 1.面向过程思想的典型栗子是C语言,C语言实现一个程序的流程是:在主函数中一步一步地罗列代码(定义子函数来罗列也是一样的道理),以此来实现我们想要的效果: 2.面向对象思想的典型 ...

  6. C++笔记005:用面向过程和面向对象方法求解圆形面积

    原创笔记,转载请注明出处! 点击[关注],关注也是一种美德~ 结束了第一个hello world程序后,我们来用面向过程和面向对象两个方法来求解圆的面积这个问题,以能够更清晰的体会面向对象和面向过程. ...

  7. PHP面向过程和面向对象

    php程序编写分为面向过程和面向对象.两者在功能实现上没有区别,但是在代码编写上区别很大,面向过程的代码很乱,不易管理,而面向对象把常用的功能封装为一个类,这样代码清楚多了. 下面举个小例子说明一下: ...

  8. python基础(23):面向过程与面向对象的优劣、初识面向对象

    1. 面向过程与面向对象的优劣 面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. 优点是:极大的降低了写程 ...

  9. 从面向过程到面向对象再到MVC

    /* * * title: 从面向过程到面向对象再到MVC * author: tanghao * date: 2020.9.30 * version: 1.0 * */ 前言 本文档通过一个显示20 ...

  10. 面向对象【林老师版】:面向过程vs面向对象(一)

    一.面向过程 1.引子 面向过程:核心是过程二字,过程指的是解决问题的步骤,设计一条流水线,机械式的思维方式优点:复杂的问题流程化,进而简单化缺点:可扩展性差 2.验证代码 import json i ...

随机推荐

  1. Java几种常见的编码方式

    几种常见的编码格式 为什么要编码 不知道大家有没有想过一个问题,那就是为什么要编码?我们能不能不编码?要回答这个问题必须要回到计算机是如何表示我们人类能够理解的符号的,这些符号也就是我们人类使用的语言 ...

  2. Hashmap的Hash()

    JDK7: public final int hashCode() {            return Objects.hashCode(getKey()) ^ Objects.hashCode( ...

  3. [原创]RedisDesktopManager工具使用介绍

    [原创]RedisDesktopManager工具使用介绍 1 RedisDesktopManager简介 一款能够跨平台使用的开源性redis可视化工具.redis desktop manager主 ...

  4. 让你提升命令行效率的 Bash 快捷键

    生活在 Bash shell 中,熟记以下快捷键,将极大的提高你的命令行操作效率. 编辑命令 Ctrl + a :移到命令行首 Ctrl + e :移到命令行尾 Ctrl + f :按字符前移(右向) ...

  5. SharePoint PowerShell 启动工作流

    前言 最近,有个需求,就是需要批量更新列表内容,平时这些操作,都用powershell去完成,但是,powershell需要在服务器上操作,而服务器权限需要通过客户的层层把关,所以,这次就考虑不用命令 ...

  6. SSE图像算法优化系列二十二:优化龚元浩博士的曲率滤波算法,达到约1000 MPixels/Sec的单次迭代速度

      2015年龚博士的曲率滤波算法刚出来的时候,在图像处理界也曾引起不小的轰动,特别是其所说的算法的简洁性,以及算法的效果.执行效率等方面较其他算法均有一定的优势,我在该算法刚出来时也曾经有关注,不过 ...

  7. 学习ReentrantLock

    1. 使用ReentrantLock import java.util.concurrent.locks.ReentrantLock; public class TestReentrantLock { ...

  8. android编码学习

    虽然以下博客有点老,但很清晰,有不明白的基础知识,可以来这里找找. 2015年最新Android基础入门教程目录(完结版) 1. 环境配置 Android stodio gradle配置踩过的坑 An ...

  9. eureka服务注册发现流程和核心参数

    参数1:eureka.instance.lease-renewal-interval-in-seconds 参数2:eureka.instance.lease-expiration-duration- ...

  10. C#缓存absoluteExpiration、slidingExpiration两个参数的疑惑

    看了很多资料终于搞明白cache中absoluteExpiration,slidingExpiration这两个参数的含义. absoluteExpiration:用于设置绝对过期时间,它表示只要时间 ...