设计模式
设计模式的基本要素
模式名称
问题
解决方案
效果
GoF23
一种思维,一种态度,一种进步
创建型模式
- 单例模式
- 工厂模式
- 抽象工厂模式
- 建造者模式
- 原型模式
结构型模式
- 适配器模式
- 桥接模式
- 装饰模式
- 组合模式
- 外观模式
- 享元模式
- 代理模式
行为型模式
-
模板方法模式
-
命令模式
-
迭代器模式
-
观察者模式
-
中介者模式
-
备忘录模式
-
解释器模式
-
状态模式
-
策略模式
-
职责链模式
-
访问者模式
OOP七大原则
- 开闭原则:对扩展开放,对修改关闭
- 里氏替换原则:继承必须确保超类所拥有的性质在子类总仍然成立
- 依赖倒置原则:要面向接口编程,不要面向实现编程
- 单一职责原则:控制类的粒度大小,将对象解耦,提高其内聚性
- 接口隔离原则:要为每个类简历他们需要的专用接口
- 迪米特原则:只与你的直接朋友交谈,不跟陌生人说话
- 合成复用原则:尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现
工厂模式
作用:
-
实现了创建者和调用者的分离
-
详细分类
-
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
OOP原则:
- 开闭原则
- 依赖倒转编程:面向接口编程
- 迪米特法则
核心本质:
- 实例化对象不使用new,用工厂方法代替
- 将选择实现类,创建对象统一管理和控制,从而将调用者跟我们的实现类解耦
三种模式
-
简单工厂模式:
-
- 用来生产同一等级结构中的任意产品(对于增加新的产品,要覆盖已有代码)
-
工厂方法模式:
-
- 用来生产同一等级结构中的固定产品(支持增加任意产品)
-
抽象工厂模式:
-
- 围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂
抽象工厂模式
定义:抽象工厂模式提供了一个创建一系列相关或者相互依赖对象的接口,无需指定他们具体的类
适用场景:
- 客户端(应用层)不依赖于产品类实例如何被创建,实现等细节
- 强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量的重复代码
- 提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现
优点:
- 具体产品在应用层的代码隔离,无需关系创建的细节
- 将一个系列的产品统一到一起创建
缺点:
- 规定了所有可能被创建的产品集合,产品簇中扩展新的产品困难
- 增加了系统的抽象性和理解难度
建造型模式
- 属于创建型模式,提供了一种创建对象的最佳方式
- 定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
- 主要作用:在用户不知道对象的建造过程和细节的情况下就可以之间创建复杂的对象
- 用户只需要给出指定的复杂对象的类型和内容,建造者模式负责按顺序创建复杂对象(把对象的建造过程和细节隐藏起来)
- 例子:
-
- 工厂(建造者模式):负责制造汽车(组装过程和细节在工厂内)
- 汽车购买者(用户):你只需要说出你需要的型号(对象的类型和内容),然后直接购买就可以使用了(不需要知道汽车时怎么组装的(车轮,车门,发动机,方向盘等等))
优点:
- 产品的建造和表示分离,实现了解耦,使用建筑者模式可以使客户端不必知道产品内部组成的细节
- 将复杂产品的创建步骤分解在不同方法中,使得创建过程更加清晰
- 具体的建造者类之间是相互独立的,这有利于系统的扩展,增加新的具体制造者无需修改原有类库的代码,符合开闭原则
缺点:
- 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制
- 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现变化,导致系统变的很庞大
原型模式
- 克隆
- Prototype
- Cloneable接口
- clone方法
浅克隆,拷贝的引用
深克隆,将对象的属性也进行克隆
结构型模式
-
作用
-
- 从程序的结构上实现松耦合,从而可以扩大整体的类结构,用来解决更大的问题
-
分类
-
- 适配器模式
- 代理模式
- 桥接模式
- 装饰模式
- 组合模式
- 外观模式
- 享元模式
适配器模式
- 将一个类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作
角色分析
- 目标接口:客户所期待的接口,目标可以是具体的或抽象的类,也可以是接口
- 需要适配的类:需要适配的类或适配者类
- 适配器:通过包装一个需要适配的对象,把原接口转换成目标对象
桥接模式
- 桥接模式是将抽象部分与它的实现部分分离,使他们都就可以独立的变化。它是一种对象结构模式,又称为柄体(Handle and Body)模式或接口(interface)模式
好处分析
- 桥接模式偶尔类似于多继承方案,但是多继承方案违背了类的单一职责原则,复用性比较差,类的个数也非常多,桥接模式是比多继承方案更好的解决办法,极大的减少了子类的个数,从而降低管理和维护的成本
- 桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统,符合开闭原则,就像一座桥,可以把两个变化的维度连接起来!
劣势分析
- 桥接模式的引入会增加系统的理解和设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计和编程
- 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性
代理模式
代理模式,SpringAOP的底层
- 静态代理
- 动态代理
静态代理
角色分析:
- 抽象角色:一般会使用接口或抽象类来解决
- 真实角色:被代理的角色
- 代理角色:代理真实角色,代理真实角色后,我们一般会做些附属操作
- 客户:访问代理对象的人
代理模式的好处:
- 使真实角色的操作更加纯粹,不用去关注一些公共的业务
- 公共业务交给代理角色去做,实现业务的分工
- 公共业务发生扩展的时候,方便集中管理
缺点:
- 一个真实角色就会产生一个代理角色,代码量会翻倍-开发效率会变低
代码步骤:
- 接口
- 真实角色
- 代理角色
- 客户端访问代理角色
动态代理
-
动态代理和静态代理角色一样
-
动态代理的代理类是动态生成的,不是我们直接写好的
-
动态代理分为两大类:基于接口的动态代理,基于类的动态代理
-
基于接口-JDK动态代理
-
基于类-cglib
-
java字节码实现:javasist
-
需要了解两个类:Proxy, InvocationHandler:调用处理程序
- 动态代理的好处
- 静态代理的好处都有
- 一个动态代理类代理的是一个接口,一般就是对应一类业务
- 一个动态代理类可以代理多个类,只要是实现了一个接口即可