术业专攻面试

23种设计模式

2019-01-20  本文已影响128人  TylooChunxia

单例模式

核心定义 一个类只有一个实例 且自行实例化并向系统提供这个实例

注意具体实例化时的多线程安全问题 通常采用饿汉或者懒汉模式

扩展的少量实例具体实现

若采用单例模式记录状态值 应注意垃圾回收机制带来的问题 可采用由容器管理单例 或者 异步记录 或者 观察者的方式 记录状态后落盘

工厂模式

核心定义 通过定义产品接口约束产品共性 定义工厂接口生产产品 同时分别实现产品和工厂接口 通过反射的方式 对调用者屏蔽创建具体对象的细节 根据类返回对象

若一个功能模块中仅需要一个工厂 则采用简单工厂模式 即直接生成工厂对象 且提供静态方法

扩展延迟初始化功能 在工厂内部保持产品状态 可通过map方式保存 需要时若map内存在 则返回 不存在则创建并返回 在此基础上 可以限制产品数量等需求 例如线程池最大数

抽象工厂模式

核心定义 多个产品 且不同产品间存在相同点 如下图所示

代码框架如下图所示

抽象类AbstractCreator类定义创建AbstractroductA及AbstractroductB的方法 Creator1及Creator2类继承抽象类分别实现对所有对应等级产品的创建逻辑 AbstractProductA及AbstractProductB抽象类定义同类产品的共性和个性方法 具体产品类继承抽象类实现个性细节

抽象工厂模式适合横向扩展 即继承AbstractCreator抽象类的实现类的扩展 不能纵向扩展 即修改AbstractCreator抽象类内部方法 因此若采用该种模式 应在设计时确定哪种为横向 哪种为纵向 方便在未来新增功能

模板方法模式

核心定义 抽象类定义基本方法及模板方法 其中模板方法禁止覆写 模板方法顺序调用基本方法 实现类继承抽象类 实现基本方法细节

特点在于模板方法顺序调用基本方法

建造者模式

核心定义 按照需求顺序组装产品类零件 并对外提供封装后的具体产品类

代码框架如下所示

CarModel抽象类采用模板模式 CarBuilder抽象类定义建造者方法 具体建造者类继承抽象建造者类 导演类根据需求具体建造者类及建造顺序新建对象 对外屏蔽实现细节

建造者模式适用相同方法不同顺序产生不同的结果的类 而工厂模式适用生产类

代理模式

核心定义 为被代理类提供代理用于控制被代理类的访问以及增强处理

静态与动态代理的区别在于编码阶段是否可知代理对象 具体使用场景如AOP

jdk动态代理仅可用于接口 cglib可用于类

具体代码如下图所示

用户接口及实现类 静态代理类 动态代理 场景类

原型模式

核心定义 实现cloneable接口覆写clone方法 通过堆内存中的二进制流复制对象

用于类重复场景

clone方法不调用构造函数 使用浅拷贝 即可变成员变量会引用同一对象 应注意安全问题

中介者模式

核心定义 将多个类之间一对多相互的耦合转换为统一对中介者类的一对一耦合 

适用于类图中出现网状结构且彼此行为有可能发生改变 MVC框架采用中介者模式

中介者模式同时会导致中介者类过于庞大

代码框架如下图所示

定义抽象类AbstractMediator持有具体同事类对象及核心执行方法exec

定义抽象类AbstractColleague持有抽象中介者类

具体同事类调用父类中中介者类exec方法表示发送请求

命令模式

核心定义 场景类通过具体命令类统一传递给调用者 调用者执行命令 命令类维护接受者类 接受者类实现逻辑

代码框架如下图所示

注意每个命令对应一个类 因此会产生命令过多情况下类过多情况

责任链模式

核心定义 将请求按照链表的方式逐级处理 对于调用方仅需调用链首节点开始传递消息即可

适用通过扩展节点至链表尾部 在不改变源码的情况下 增强功能

具体代码如下

请求类 请求等级 处理节点抽象类 处理节点实现类 场景类

处理节点父类负责选择合适节点处理 处理节点子类则只需关注处理逻辑

装饰模式

核心定义 抽象装饰类继承抽象被修饰类并通过构造函数维护被修饰类 具体抽象类继承抽象装饰类

适用多重子类继承情况

具体代码如下所示

抽象被装饰类及具体被装饰类 抽象装饰类及具体装饰类 场景类

策略模式

核心定义 抽象策略类定义抽象方法 具体抽象类继承抽象策略类 角色类维护抽象策略类并对外提供调用方法

代码框架如下所示

当策略超过4个 应当结合工厂模式的混编模式

适配器模式

核心定义 通过中间类解决两个类或接口不兼容问题

若新业务类单一 则适配器类采用继承方式 否则若新业务类多个 采用聚合方式 即适配器类维持多个新业务类

具体代码框架如下

迭代器模式

极古老模式 不需要学习使用 略过

组合模式

核心定义 通过抽象类定义公共方法 各子类继承抽象类实现个性方法 整体实现树形结构

代码框架如下图所示

观察者模式

核心定义 被观察者类触发动作同时通知观察者类方法

若仅一对观察与被观察对象 可采用函数作参数通过回调方式实现

若被观察与观察者关系为一对多 则通过被观察者实现Observable接口在具体方法中通知观察者

门面模式

核心定义 子系统对外通过门面类进行控制访问 不参与逻辑处理 例如子系统方法调用顺序

当多个门面类时 作用范围小的门面类应当持有作用范围大的门面类 通过调用大范围门面类提供方法 避免重复代码

备忘录模式

核心定义 发起者类拥有当前对象 备忘录类通过map维持单个发起者多状态 备忘录管理者类通过map维持多个备忘录状态

代码框架如下图所示 不完全准确

访问者模式

核心定义 定义抽象被访问者类包含公共属性及接受方法 具体被访问者类实现个性属性及方法 访问者接口定义访问具体被访问者类方法 具体访问者类实现访问细节

代码框架如下图所示

将数据处理从面向过程转化为面对对象的方式 同时将底层模块的数据处理转移到高层模块的数据处理上 保持单一职责原则

适用遍历对象下的属性处理

在该模式中注意区分静态绑定和动态绑定的区别

状态模式

核心定义 状态类与上下文类互相持有对象 表现为1对多的关系 通过上下文类对状态类的改变 从而表现出对外部的行为的改变

具体代码如下所示

抽象状态类 具体状态类 上下文类     场景类

抽象状态类持有上下文类对象及定义所有空的状态转换方法 具体状态    类覆写相应状态转换方法 上下文类持有所有具体状态类及当前状态 提供所有状态转换方法

解释器模式

核心定义 定义多个抽象解释器类并由具体解释器类实现细节

由于有许多开源框架或脚本语言可代替 该模式不常用

享元模式

核心定义 将实体类中内部状态及外部状态剥离 以外部状态组合的方式存放享元池 从享元池获得数据后再填充内部状态 从而大量减少重复元素

适用场景为大量相似对象

抽象类 实体类 享元池类 场景类

桥接模式

核心定义 抽象与实现解耦

代码框架如下图所示

上一篇下一篇

猜你喜欢

热点阅读