1.常用的编程思想:
(1).面向过程编程(opp)Procedure Oriented Programming : 以过程为中心的编程思想。
(2).面向对象编程(oop)Object Oriented Programming : 以对象为基础的编程思想
(3).面向切面编程(aop) Aspect Oriented Programming : 基于OOP延伸出来的编程思想,横插一杠。
(4).函数式编程(FP) Functional programming:本质是函数的组合
o:object p:program a:
opp(C语言):
分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。类似一串珠子。
构成问题事务分解成各个对象。一切皆为对象的思想。
对象有属性及方法(自身带啥特征,有啥能力,如:人:属性有鼻子有眼,能力:能跑能跳还能说话)
特点(封装,继承,多态),各种五花八门的能力和特性都有,大多设计模式都基于多态这个特性。
面向对象vs面向过程:
优:
1)数据抽象的概念可以在保持外部接口不变的情况下改变内部实现,从而减少甚至避免对外界的干扰;
2)通过继承大幅减少冗余的代码,并可以方便地扩展现有代码,提高编码效率,也减低了出错概率,降低软件维护的难度;
3)结合面向对象分析、面向对象设计,允许将问题域中的对象直接映射到程序中,减少软件开发过程中中间环节的转换过程;
4)通过对对象的辨别、划分可以将软件系统分割为若干相对为独立的部分,在一定程度上更便于控制软件复杂度;
5)以对象为中心的设计可以帮助开发人员从静态(属性)和动态(方法)两个方面把握问题,从而更好地实现系统;
6)通过对象的聚合、联合可以在保证封装与抽象的原则下实现对象在内在结构以及外在功能上的扩充,从而实现对象由低到高的升级。 [3]
缺:
(1)运行效率较低。
(2)类库庞大。
aop:(jave-Spring,java-AspectJ)
基于OOP延伸出来的编程思想。主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。一般都是对于框架来说的。
哪里体现?
联想一下laravel的中间件、javaweb的拦截器、vue的Decorator…它们都是AOP思想的实践。装饰器模式、代理模式,它们也是基于AOP思想的设计模式。
AOP思想,指导我们通过找到平整切面的形式,插入新的代码,使新插入的代码对切面上下原有流程的伤害降到最低。
常用的地方:
laravel中间件:权限,日志,请求参数过滤,请求频率限制等等
面向对象vs面向切面:
领域不同:
一个是实体及其属性和行为进行抽象封装,一个是处理过程的某个步骤或阶段
事实上许多项目上OPP、OOP、AOP是同时存在的,各种的领域不同,相互配合
FB:(go)
什么是函数式编程,这并没有唯一定义,它只是广泛聚合了一些编程风格的特性,我们可以将它与面向对象编程OOP进行对比,两者区别是,OOP最大优点是多态性和封装;而FP优势是不变性及其声明性风格,两者其实是十字正交,可互补的,可在同一程序中共存。
go语言编程体现得比较明显
面向对象vs函数式编程:
面向对象:
- 数据和对数据的操作紧紧耦合,封装在一个类Class中(充血模型)。这里的数据是可变的。
- 数据的变化更改需要通过数据的操作方法实现,类以外方法不能直接操作更改一个类内部的数据属性。
- 类或对象隐藏它们操作的实现细节,其他对象调用这些操作只需要通过接口。
- .核心抽象模型是数据和数据的关系。
- 增加功能通常是组合新对象和拓展已经存在的对象,并加入新的方法实现的。
函数编程:
- 数据与函数是松耦合的,两者是分离的,数据是纯数据(失血模型),函数没有与数据封装在一起。这里的数据是不可变的。
- 函数隐藏了它们的内部实现,语言的抽象是函数,以及将函数组合起来表达。
- 核心抽象模型是函数和函数的组合交换。
- 通常增加功能是通过编写新的函数实现。
- 变量缺省是不可变的,一旦赋值就不能再被改变,减少可变性变量的使用会提升并发性。
面向对象侧重于分解,函数编程侧重于组合,两者配合使用才能发挥各自优点
2.程序的本质:
数据访问,处理,结果存储。循环往复,中间穿枝插叶。
数据存放方式:
(1)oop:数据存放在对象的属性里面,以及静态成员(全局变量)
(2) 函数: 数据存放在闭包(各级作用域)里面,作用域包括全局作用域
数据获取方式:
(1)oop:访问数据(全局变量除外)需要先获取对象的引用,然后再进行操作(直接访问——公共属性,或者调用成员函数/方法访问——私有属性)
(2) 函数: 直接函数调用(通过函数入参或者作用域链查找)
OO是通过持有,以及传递对象的方式去让别的对象来操作数据,而对象也会是其他对象的成员,层层嵌套。当你想要访问某一个数据的时候,就需要顺着对象的引用链条去找,一步步去操作。
函数式传递的则是函数,调用函数即操作数据,传递函数的时候其实隐含着传递了函数创建的时候所附带的作用域,这个在表面上看不出来,在底层是有的。
3.内存表现
基本数据类型/引用数据类型/对象实例/static 内存示意图
- 寄存器:JVM内部虚拟寄存器,存取速度非常快,程序不可控制。
- 栈:保存局部变量的值:包括1.基本数据类型的值。2.保存类的实例,即堆区对象的引用(指针)。3.保存加载方法时的帧。
- 堆:用来存放动态产生的数据,比如new出来的对象。注意创建出来的对象只包含属于各自的成员变量,并不包括成员方法。因为同一个类拥有各自的成员变量,存储在堆中的不同位置,但是同一个类不同实例的他们共享该类的方法,并不是每创建一个对象就把成员方法复制一次。
- 常量池:JVM为每个加载的类型维护一个常量池,常量池是这个类型用到的常量的集合。包括直接常量(基本类型,String)和对其他类型、方法、字段的符号引用(1)。池中的数据和数组一样通过索引访问。由于常量池包含了一个类型所有的对其他类型、方法、字段的符号引用,所以常量池在Java的动态链接中起了核心作用。常量池存在于方法区中,而方法区存在于堆中。