IT - 面向对象/设计原则/设计模式/编码规范
2021-07-15 20:37:18 0 举报
AI智能生成
面向对象知识笔记
作者其他创作
大纲/内容
面向对象
概念
面向对象是一种编程范式;在进行程序设计的过程中,将现实世界中的事物或活动设计为类,然后协调类创建的对象完成系统功能
面向对象编程因为其具有丰富的特性(封装、抽象、继承、多态),可以实现很多复杂的设计思路,是很多设计原则、设计模式等编码实现的基础。
面向对象围绕着对象或类来做需求分析和设计的。分析和设计两个阶段最终的产出是类的设计,包括程序被拆解为哪些类,每个类有哪些属性方法,类与类之间如何交互等等。它们比其他的分析和设计更加具体、更加落地、更加贴近编码,更能够顺利地过渡到面向对象编程环节。这也是面向对象分析和设计,与其他分析和设计最大的不同点。
四大特性
封装
抽象
继承
多态
面向对象分析
面向对象分析就是要搞清楚做什么
面向对象设计
面向对象设计就是要搞清楚怎么做。两个阶段最终的产出是类的设计,包括程序被拆解为哪些类,每个类有哪些属性方法、类与类之间如何交互等等。
面向对象编程
概念
面向对象编程是一种编程范式或编程风格。它以类或对象作为组织代码的基本单元,并将封装、抽象、继承、多态四个特性,作为代码设计和实现的基石 。
面向对象编程语言是支持类或对象的语法机制,并有现成的语法机制,能方便地实现面向对象编程四大特性(封装、抽象、继承、多态)的编程语言。
设计原则
概念
设计原则是指导我们代码设计的一些经验总结,对于某些场景下,是否应该应用某种设计模式,具有指导意义。比如,“开闭原则”是很多设计模式(策略、模板等)的指导原则。
原则
(SOLID)
单一职责原则(SRP:Single Responsibility Principle)
一个类只能承担一个事情
其实就是开发人员经常说的”高内聚,低耦合”
也就是说,每个类应该只有一个职责,对外只能提供一种功能,而引起类变化的原因应该只有一个。在设计模式中,所有的设计模式都遵循这一原则。
开闭原则(OCP: Open Closed Principle)
一个对象对扩展开放,对修改关闭。
对类的改动是通过增加代码进行的,而不是修改现有代码。
也就是说软件开发人员一旦写出了可以运行的代码,就不应该去改动它,而是要保证它能一直运行下去,如何能够做到这一点呢?这就需要借助于抽象和多态,即把可能变化的内容抽象出来,从而使抽象的部分是相对稳定的,而具体的实现则是可以改变和扩展的。
里式替换原则(LSP: Liskov Substitution Principle)
子类型能够替换它们的基类型
在任何父类出现的地方都可以用它的子类来替代。
其实就是说:同一个继承体系中的对象应该有共同的行为特征。
接口隔离原则(ISP: Interface Segregation Principle)
抽象不持有特定逻辑,应持有实现的公有逻辑
一个接口不需要提供太多的行为,一个接口应该只提供一种对外的功能,不应该把所有的操作都封装到一个接口中。
依赖倒置原则(DIP: Dependency Inversion Principle)
要依赖于抽象,不要依赖于具体实现。
在应用程序中,所有的类如果使用或依赖于其他的类,则应该依赖这些其他类的抽象类,而不是这些其他类的具体类。为了实现这一原则,就要求我们在编程的时候针对抽象类或者接口编程,而不是针对具体实现编程。
DRY
不做重复的事,不写重复类似的代码
KISS
keep it simple,尽量简单的代码,让代码更容易被别人理解
YANGNI
you ain't gonna need it,只着眼必需的功能,不添加认为可能需要的功能
LOD 迪米特原则
一个对象应当对其他对象尽可能少的了解
降低各个对象之间的耦合,提高系统的可维护性。在模块之间应该只通过接口编程,而不理会模块的内部工作原理,它可以使各个模块耦合度降到最低,促进软件的复用
其他
降低系统耦合度,复杂度
相关的“在一起”,叫内聚,不相关的“在一起”,叫耦合。
维护性,复用性,灵活性,扩展性
设计模式
是什么
设计模式是针对软件开发中经常遇到的一些设计问题,总结出来的一套解决方案或者设计思路。
大部分设计模式要解决的都是代码的可扩展性问题。
从抽象程度上来讲,设计原则比设计模式更抽象。设计模式更加具体、更加可执行。
24种设计模式
创建型(6种)
概念
主要解决对象的创建问题,封装复杂的创建过程,解耦对象的创建代码和使用代码。
种类
单例模式
概念
一个类只允许创建一个对象(或者叫实例),那这个类就是一个单例类,这种设计模式就叫作单例设计模式,简称单例模式。
场景
一个类只能有一个实例
一个类多个实例会存在问题的时候
资源抢占
种类
饿汉式
使用static关键字,类加载的时候实例化
不支持延迟加载
线程安全
懒汉式
支持延迟加载
性能不如饿汉式
双重校验锁
支持延迟加载
线程安全,性能好
类似懒汉式,基于懒汉式改造
静态内部类
支持延迟加载
类似饿汉式,基于饿汉式改造
原理:类加载机制,内部静态类在使用时才会被加载
枚举
支持延迟加载
线程安全
需要考虑的问题点
创建对象的线程安全问题
是否支持延迟加载
在真正用到对象的时候才创建
构造函数需要private访问权限
考虑getInstance()性能是否高(是否加锁)
工厂模式
定义了一个创建对象的接口, 但由子类决定要实例化的类是哪一个. 工厂方法让类把实例化推迟到子类
场景
不同条件创建不同实例
组成
精彩评价
跟整理衣服差不多。衣服少的时候,都放一起,多的时候,按照一定规则分一下,整理一下子
简单工厂模式
定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。
场景
对于产品种类相对较少的情况,考虑使用简单工厂模式。使用简单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑,可以很方便地创建所需产品。
特点
优点:
工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例。客户端可以免除直接创建产品对象的职责,很方便的创建出相应的产品。工厂和产品的职责区分明确。
客户端无需知道所创建具体产品的类名,只需知道参数即可。
也可以引入配置文件,在不修改客户端代码的情况下更换和添加新的具体产品类。
缺点:
简单工厂模式的工厂类单一,负责所有产品的创建,职责过重,一旦异常,整个系统将受影响。且工厂类代码会非常臃肿,违背高聚合原则。
使用简单工厂模式会增加系统中类的个数(引入新的工厂类),增加系统的复杂度和理解难度
系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂
简单工厂模式使用了 static 工厂方法,造成工厂角色无法形成基于继承的等级结构。
工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例。客户端可以免除直接创建产品对象的职责,很方便的创建出相应的产品。工厂和产品的职责区分明确。
客户端无需知道所创建具体产品的类名,只需知道参数即可。
也可以引入配置文件,在不修改客户端代码的情况下更换和添加新的具体产品类。
缺点:
简单工厂模式的工厂类单一,负责所有产品的创建,职责过重,一旦异常,整个系统将受影响。且工厂类代码会非常臃肿,违背高聚合原则。
使用简单工厂模式会增加系统中类的个数(引入新的工厂类),增加系统的复杂度和理解难度
系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂
简单工厂模式使用了 static 工厂方法,造成工厂角色无法形成基于继承的等级结构。
对于产品种类相对较少的情况,考虑使用简单工厂模式。使用简单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑,可以很方便地创建所需产品。
组成
简单工厂(SimpleFactory):是简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
抽象产品(Product):是简单工厂创建的所有对象的父类,负责描述所有实例共有的公共接口。
具体产品(ConcreteProduct):是简单工厂模式的创建目标。
建造者模式
使用生成器模式封装一个产品的构造过程, 并允许按步骤构造. 将一个复杂对象的构建与它的表示分离, 使得同样的构建过程可以创建不同的表示。。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
组成
产品
抽象建造者
具体建造者
指挥者
产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件。
抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。
具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。
场景
相同的方法,不同的执行顺序,产生不同的结果。
多个部件或零件,都可以装配到一个对象中,但是产生的结果又不相同。
产品类非常复杂,或者产品类中不同的调用顺序产生不同的作用。
初始化一个对象特别复杂,参数多,而且很多参数都具有默认值。
特点
该模式的主要优点如下:
封装性好,构建和表示分离。
扩展性好,各个具体的建造者相互独立,有利于系统的解耦。
客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险。
其缺点如下:
产品的组成部分必须相同,这限制了其使用范围。
如果产品的内部变化复杂,如果产品内部发生变化,则建造者也要同步修改,后期维护成本较大。
封装性好,构建和表示分离。
扩展性好,各个具体的建造者相互独立,有利于系统的解耦。
客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险。
其缺点如下:
产品的组成部分必须相同,这限制了其使用范围。
如果产品的内部变化复杂,如果产品内部发生变化,则建造者也要同步修改,后期维护成本较大。
资料
多例模式
在一个解决方案中结合两个或多个模式, 以解决一般或重复发生的问题
原型模式
当创建给定类的实例过程很昂贵或很复杂时, 就使用原型模式.
场景
创建一个对象成本高(比如需要io获取到,网络获取到,或者计算很多逻辑获取到),但是拥有另外一个大部分数据一直的对象,则可以从已有的对象种直接拷贝。
结构型
主要解决“类或对象的组合”问题
种类
代理模式
适配器模式
将一个类的接口, 转换成客户期望的另一个接口. 适配器让原本接口不兼容的类可以合作无间. 对象适配器使用组合, 类适配器使用多重继承.
桥接模式
使用桥接模式通过将实现和抽象放在两个不同的类层次中而使它们可以独立改变.
装饰者模式
动态地将责任附加到对象上, 若要扩展功能, 装饰者提供了比继承更有弹性的替代方案.
组合模式
允许你将对象组合成树形结构来表现"整体/部分"层次结构. 组合能让客户以一致的方式处理个别对象以及对象组合.
行为型
主要解决的就是“类或对象之间的交互”问题
种类
观察者模式
模板模式
策略模式
职责链模式
迭代器模式
状态模式
访问者模式
备忘录模式
命令模式
解释器模式
中介模式
类的关系
依赖
类A当中使用了类B,其中类B是作为类A的方法参数、方法中的局部变量、或者静态方法调用。
关联
类A当中使用了类B作为成员变量;同时类B中也使用了类A作为成员变量。
聚合
组合
继承
实现
编码规范
作用
编程规范主要解决的是代码的可读性问题
编码规范相对于设计原则、设计模式,更加具体、更加偏重代码细节、更加能落地
持续的小重构依赖的理论基础主要就是编程规范。
规范
命名(类,方法,变量,表名,字段名)
系统
业务分层
模块拆解
代码
命名
类名
方法名
变量名
数据库
表,数据库命名
编码,字符集,排序规则
通用字段
索引
关联字段需要长度类型一致,并且在注释中写明是哪个表的哪个字段
经验
代码重构
持续重构是保持代码质量不下降的有效手段,能有效避免代码腐化到无可救药的地步。
设计思想、设计原则、设计模式一个最重要的应用场景就是在重构的时候。
0 条评论
下一页