工厂模式:
- 简单工厂模式:
定义一个工厂类,根据传入的参数不同返回不同的实例,被创建的实例具有共同的父类或接口
适用场景:
(1)需要创建的对象较少。
(2)客户端不关心对象的创建过程。
- 工厂方法模式:
每一个类型设置一个工厂,生产不同类型
针对不同的对象提供不同的工厂。也就是说每个对象都有一个与之对应的工厂。
定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。
public interface Reader { void read(); }
public class JpgReader implements Reader {
@Override
public void read() {
System.out.print("read jpg");
}}
public interface ReaderFactory { Reader getReader(); }
public class JpgReaderFactory implements ReaderFactory {
@Override
public Reader getReader() {
return new JpgReader();
}}
ReaderFactory factory=new JpgReaderFactory();
Reader reader=factory.getReader();
reader.read();
- 抽象工厂模式:
创建一系列相互关联互相依赖的产品族
抽象工厂模式是工厂方法的仅一步深化,在这个模式中的工厂类不单单可以创建一个对象,而是可以创建一组对象
(1)和工厂方法一样客户端不需要知道它所创建的对象的类。
(2)需要一组对象共同完成某种功能时。并且可能存在多组对象完成不同功能的情况。
(3)系统结构稳定,不会频繁的增加对象。
享元模式(flyweight):
减少创建对象的数量,以减少内存占用和提供性能。当系统中存在多个相同对象,只需要共享一份对象拷贝(提高性能)
基本逻辑:抽象享元interface <--- 具体享元实现类 <--- 享元工厂创建实现类 <--- Main调用
享元模式与单例模式区别_樊城城的博客-CSDN博客_享元模式和单例模式的区别
单例模式是类级别的,一个类只能有一个对象实例;
享元模式是对象级别的,可以有多个对象实例,多个变量引用同一个对象实例;
代理模式:
为其他对象提供代理,并通过代理访问(达到控制访问的目的)
工厂模式和代理模式的区别:
- 工厂是提供创建接口实例逻辑的封装,目的是让其他类依赖于接口和工厂,而非具体的实现类
- 代理是增加中间层,从而在中间进行额外的逻辑,比如懒惰初始化,比如封装远程调用,比如可以增加访问控制
屏蔽用户真实的对象访问:1、安全问题 2、远程调用 3、提高系统性能
动态代理:代理类与委托类关系在运行时确定,无代理类字节码,反射机制动态生成
编程基本逻辑:接口 <--- 实现类 <--- 代理 <--- 主函数
字节码-->类-->实例
静态代理与动态代理的区别:字节码是否由JVM动态生成,动态代理中使用了反射去创建对象
- 静态:由程序员创建代理类或特定工具自动生成源代码再对其编译。在程序运行前代理类的.class文件就已经存在了
- 动态:在程序运行时运用反射机制动态创建而成
静态代理和动态代理的理解_Wangqyoho的博客-CSDN博客_动态代理和静态代理简单理解
Hibernate代理模式:1、延迟加载 2、关联表延迟加载
先使用代理,在真正调用到getter方法时,使用SQL取对象
装饰者模式:委托机制动态添加对象的功能
在无须改变原有类以及类的继承者关系的情况下,动态扩展一个类的功能
通过装饰者来包裹真实的对象,并动态地向对象添加或者撤销功能
举例:
interface A
B implements A
C implements A
D extends C
E extends C
A a = new E(D(B)); //组装
OutputStream ---> FileOutputStream ---> BufferedOutputStream
(自动预读更多的字节数据到它自己维护的被内部字节缓冲区中,减少系统调用次数)
流 通道
InputStream ---> FileInputStream ---> BufferedInputStream
Writer ---> FileWriter ---> BufferedWwriter
Reader ---> FileReader ---> BufferedReader
通道(流)
new DataOputStream(new BufferedOutputStream(new FileOutputStream(......)))
// Decorator <--- DataOutputStream <--- BufferedOutputStream <--- FileOutputStream
适配器模式:
旧的类保持原有状态,新的适配器类对旧类进行适配的同时,添加自己的方法
应用:Enmeration -> Iterator
interface:适配后目的类
Source:待适配的类
Adaptor:适配器
装饰者模式 & 适配器模式对比:
装饰者模式:同一簇
适配器模式:不同簇
观察者模式:事物变化了会去通知观察者
ISubject(事物) ---> IOSserver(观察者)
| |
具体事物 具体观察者
ISubject{ IOServer{
//添加观察者 //处理逻辑
//删除观察者 }
//通知观察者
}
典型实现:
AbstractButton ---> finalActionPermed ---> ActionListener actionPerformed()
|
JButton
模版方法模式:
提供一个抽象类,将部分逻辑以具体方法或构造器形式实现,然后声明一些抽象方法来迫使子类实现剩余逻辑。
JDK使用的设计模式:
- 装饰者模式:IO流
- 迭代器模式:Iterator
- 单例模式: Java.lang.Runtime
- 代理模式: RMI
其他补充:
责任链模式:
用于避免请求发送者与多个请求处理者耦合在一起,让所有请求的处理者持有下一个对象的引用
从而将请求串联在一条链,在由请求发生时,可将请求沿着这条链传递,知道遇到核心处理器
主要角色:
Handler接口: 用于规定在责任链上具体要执行的方法
AbstractHandler:持有Handler实例并通过setHandler() 和 getHandler() 将各个具体业务Handler串联成一个责任链
业务Handler: 用户根据具体的业务需要实现的业务逻辑
命令模式:
将请求封装为命令基于事件驱动异步执行,以实现命令的发送者和命令的执行者之间的解耦
主要角色:
抽象命令类:执行命令的接口,定义执行命令的抽象方法 execute()
具体命令类:抽象命令类的实现类,持有接受者对象,并在接收到命令后调用命令执行者的方法action()实现命令的调用和执行
命令执行者:命令的具体执行者,定义了命令执行的具体方法action()
命令调用者:接收客户端的命令并异步执行
解释器:
给定一种语言,并定义该语言的表示,用于SQL解析,符号处理引擎
主要角色:
抽象表达式(Abstract Expression):定义解析器的接口,约定解释器所包含的操作,比如interpret()
终结符表达式(Terminal Expression):用来定义语法中和终结符有关的操作
非终结符表达式(Nonterminal Expression):抽象表达式子类
环境
迭代器:提供了顺序访问集合对象中的各个元素,而不暴露该对象内部结构的方法
中介者(调停模式):
对象和对象之间不直接交互,而是通过中介者角色进行交互。使得原有对象之间关系变得松散
主要角色:
抽象中介者:定义了注册同事对象方法和转发同事对象信息的方法
具体中介者:定义了一个List来保存同事对象,协调各个同事角色之间的交互关系
抽象同事类:持有中介对象,并定义同事对象交互的抽象方法,同时实现同事类的公共方法和功能
具体同事类:在需要与其他同事对象交互时,通过中介者对象完成
备忘录模式:
快照模式,将对当前对象的内部状态保存到备忘录中,以便在需要时能将该对象的状态恢复到原先保存的状态
主要角色:
发起人 Originator: 记录当前时刻对象的内部状态,定义创建备忘录和恢复备忘录数据的方法
备忘录 Memento: 负责存储对象的内部状态
状态管理者 Storage: 对备忘录的历史状态进行存储,定义了保存和获取备忘录状态的功能
观察者模式:
被观察者状态发生变化时,系统基于事件驱动将状态通知到顶叶其他状态的观察者中
包括:
抽象主题:持有订阅了该主题的观察者对象集合,提供增加、删除观察者,和主题状态变化的通知方法
具体主题:实现了抽象主题的通知方法,在主题内部变化时,通知订阅的对象
抽象观察者:观察者的抽象类或接口,定义了主题状态变化时需要调用的方法
具体观察者:抽象观察者的实现类,在收到主题状态变化的信息后执行具体的触发动作
状态模式:
给对象定义不同的状态,并为不同的状态定义不同的行为,在对象的状态发生变换时自动切换状态行为。
例如:工作状态---开会,写ppt,做设计
休假状态---旅游,休息等
环境(Context): 用于维护对象当前状态,并在对象状态发生变化时触发对象行为的变化
抽象状态(AbstractState): 定义不同状态对应的行为
具体状态(Concreate State): 实现抽象状态所定义的行为
策略模式:
Strategy:策略接口
concreateTrategy:基础策略
Context:基础环境上下文,持有Strategy
模版方法:
定义了一个算法框架,通过继承的方式将算法的实现延迟到子类中
抽象类:定义了算法的框架,由基本方法和模版方法组成
具体子类:实现在抽象类中定义的算法
访问者模式:
访问者模式通过定义不同的访问者实现对数据的不同操作。
适用数据结构稳定但是数据操作方式多变的系统中(例如公司不同权限的管理者)
抽象访问者
具体访问者
抽象元素:定义该元素的入口
具体元素:具体访问不同类型,实现不同的业务逻辑
建造者模式:
主要用于解决软件系统中复杂对象的创建问题
建造者模式与工厂模式的最大区别是:
- 建造者模式更关注产品的组合方式和装配顺序(例如组装电脑,需要有组装CPU、内存等步骤)
- 工厂模式关注产品的生产本身
浅复制:通过实现Coneable接口并覆写其Clone方法实现
- 对象的基本数据类型变量值会重新被复制和创建,引用的数据类型仍指向原对象引用
(浅复制不复制对象的引用类型数据)
深复制:不论数据类型和应用数据类型,都会被重新复制和创建
单例模式:
- 饿汉模式:
public class HungrySingleton {
private static HungrySingleton instance = new HungrySingleton();
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return instance;
}
}
- 懒汉模式:
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {
}
public static synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
- 双重锁定:
public class Lock2Singleton {
private volatile static Lock2Singleton singleton;
private Lock2Singleton() {
}
public static Lock2Singleton getInstance() {
if (singleton == null) {
synchronized (Lock2Singleton.class) {
if (singleton == null) {
singleton = new Lock2Singleton();
}
}
}
return singleton;
}
}
- 静态实例:
public class StaticSingleton {
private static class SingletonHolder {
private static final StaticSingleton INSTANCE = new StaticSingleton();
}
private StaticSingleton() {
}
public static final StaticSingleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
桥接模式:通过将抽象及其实现解耦,使二者可以根据需求独立变化。
主要用于解决需求多变的情况下,使用继承造成的类爆炸问题
例如:JDBC和DriverManager就使用了桥接模式
Driver:接口
包括具体接口实现类
DriverManagerBridge:抽象类,持有Driver对象
包括具体Driver实现类
外观模式:通过门面(facade)向客户端提供一个统一的系统访问接口