面向对象编程(OOP,Object Oriented Programming)
是一种编程范式或编程风格。以类或对象作为组织代码的基本单元,并将封装、抽象、继承、多态四个特性作为代码设计和实现的基石。
封装
编程语言通过语法机制来
控制访问权限
来隐藏信息、保护数据,java通过public等四种来控制。即使private也可用反射访问,意义不在于绝对安全,而是易用性。
- 封装目的在于提高易用性和数据安全性,适度暴露,适当对调用者屏蔽细节。
抽象(有时不被看作面向对象编程特性)
隐藏方法的实现,让使用者只需专注功能,不需了解细节。java中使用接口或抽象类来实现抽象特性
-
抽象是一种只关注功能点不关注实现的设计思路,可以帮助我们过滤掉很多非必要信息。
-
抽象概念是非常通用且宽泛的设计思想,在代码设计中有非常重要的指导作用。很多设计原则中体现了这种思想,比如基于接口而非实现编程、开闭原则(扩展开、修改关)、代码解耦等。
继承
表示
is-a
,分单继承和多继承,是编程语言提供的语法机制,如:java中extends
- 继承主要解决代码复用问题。
- 这个特性争议性很强,很多人认为是一种反模式,应该尽量少用;
多用组合少用继承
。
多态
表示
has-a
或者behaive like
关系,指相同消息根据不同对象引发不同行为(消息发送为函数调用)。大部分实现多态的技术:动态绑定,执行期间判断所引用的实际类型,根据实际类型调用。
实现多态的两种形式:重载、覆盖。
重载:仅因功能类型,函数名一样,参数个数不一样,增加可读性,仅此而已。
覆盖(重写):参数、返回不能修改,异常减少或无,访问权限更广。
设计原则
类亦可指模块,但模块可是多个类、函数、功能模块等
SOLID
- SRP单一职责原则:类或模块职责单一
- OCP开闭原则:对扩展开闭,对修改关闭
- LSP里式替换原则:子类可以扩展父类的功能,但不能改变父类原有的功能。
- ISP接口隔离原则:接口尽量单一、小或者说更具体,让接口只包含调用方感兴趣的方法
- DIP依赖倒置原则:高层模块不依赖低层模块,两者应该通过抽象互相依赖;抽象不依赖具体实现细节,具体实现细节依赖抽象;核心思想:要面向接口编程,不要面向实现编程。
单一职责注重职责,接口隔离注重对接口的依赖;单一职责是约束类,主要针对实现和细节,接口隔离约束接口,主要针对抽象和程序整体框架的构建。两个都是为了提高类的内聚性、降低类之间耦合,体现了封装的思想。
KISS原则与YAGNI原则
KISS原则讲的是“如何做的问题”(尽量保持简单),而YAGNI原则说的是“要不要做”的问题(当前不需要就不要做)。
KISS原则
Keep It Simple and Stupid.
Keep It Short and Simple.
Keep It Simple and Straightforward.
- 不要使用同事可能不懂的技术来实现代码。
- 不要重复造轮子,要善于使用已有的工具类库。
- 不要过度优化。不过度使用一些奇技淫巧来优化代码,牺牲可读性。
YAGNI原则
You Ain’t Gonna Need It
不要过度设计
DRY原则
Don’t Repeat Yourself
Rule of Three原则
三种重复
实现逻辑重复、功能语义重复、代码执行重复;
三种重复,有时重复不违反DRY,有时不重复却违反DRY,需具体分析。
LOD法则设计模式(Law of Demeter——迪米特法则)
The Least Knowledge Principle。最小知识原则
不该有直接依赖关系的类之间,不要有依赖;有依赖关系的类之间,尽量只依赖必要的接口(也就是定义中的“有限知识”)。
- 希望减少类之间的耦合,让类越独立越好。
- 每个类都应该少了解系统的其他部分。一旦发生变化,需要了解这一变化的类就会比较少。
高内聚、松耦合
非常重要的设计思想,能够有效的提高代码的可读性和可维护性,缩小功能改动导致的代码改动范围。
- 高内聚指类本身,松耦合指类与类之间的依赖关系的设计。
- 高内聚指相近的功能应在同一个类中,不相近的功能不要放在同一类中;相近的功能往往会在修改时比较集中。
- 松耦合指在代码中,类与类之间的依赖关系简单清晰。即使两个类有依赖关系,一个类修改也不会或很少导致依赖类改动。
控制反转、依赖反转、依赖注入
IOC(Inversion Of Control,非spring ioc)
控制指对程序执行流程的控制,而反转指的是没有使用框架之前,程序员自己控制整个流程;在使用框架后整个程序的执行流程通过框架控制。流程的
控制权
从程序员反转
到框架;是一个比较笼统的设计思想,一般用来指导框架层面的设计。
DI(Dependency Injection——依赖注入)
一种具体的编码技巧。
不通过new()的方式在类内部创建依赖对象,而是将依赖对象在外部创建好,通过构造函数、函数参数等方式传递(或注入)给类使用。
依赖注入框架(DI Framework)
控制反转容器是一种非常宽泛的描述,DI 依赖注入框架的表述更具体、更有针对性。实现控制反转的方式有很多,除了依赖注入,还有模板模式等,而 Spring 框架的控制反转主要是通过依赖注入来实现的。不过这点区分并不是很明显。
依赖反转原则(DIP——Dependency Inversion Principle,亦称依赖倒置原则)
High-level modules shouldn’t depend on low-level modules. Both modules should depend on abstractions. In addition, abstractions shouldn’t depend on details. Details depend on abstractions.
- 高层低层划分,调用者属于高层,被调用者属于低层。