pattern-design
- 所有模式使用的基本方式:
继承(is-a)、委托(组合:has-a); 实现主要是通过反射 - 比较重要的模式:
代理、策略. - 类最基本的三个关系
- is-a: 通过继承实现,
A extends B - has-a: 通过组合实现,
B是A的一个元素(get/set) - use-a: 通过参数传递实现, 比如回调函数(callback)
- is-a: 通过继承实现,
- pattern-design
创建
工厂
抽象工厂
建造者
原型
单例
结构
适配器
桥接
组合
装饰
外观
享元
代理
行为
责任链
命令
迭代器
中介
备忘录
观察者
状态
策略
模版
访问者
代理模式-委托模式-proxy
实现方式:(继承或委托)
死代码的静态代理->动态代理(jdk,cglib)
- 静态代理
- 死代码,即使装饰着模式|委托模式
- 动态代理
- jdk代理
- cglib代理
Jdk (注入)
- 1.使用了注入的方式, 目标类必须实现某接口,getInterfaces()不能为null
- 2.代理类与目标类的关系是has(依赖)关系
- 3.InvocationHandler,Proxy.newProxyInstance
- 4.系统解耦方便
CGlib (继承)
- 1.基于asm原理,基于对class字节码修改,生成代理子类代理类是目标类的继承
- 2.方法必可继承,不能private, final
- 4.MethodInterceptor,Enhancer.create()
使用误区: but was actually of type 'com.sun.proxy.$Proxy37'
//使用的类注入: 只支持cglib代理
@Autowired
HelloServiceImpl helloService;
//使用的接口注入:支持jdk,cglib代理
@Autowired
HelloService helloService;
//jdk支持接口代理,cglib支持类和接口代理
//源代码
spring-jdk代理实现类JdkDynamicAopProxy
Spring-cglib代理实现类CgLibCommonProxy
spring处理代理的aware类的方法:
单例模式 - single (反射)
-
Q1: Jvm回收单例内存的时机:
- A: 类没有对应的实例存在 && Class对象从永久代删除,不能被反射
-
Q2: 什么情况下出现多个单利:
- A1: 分布式系统 | 多个jvm
- A2: 不用的classLoader
- A3: 不同的序列化方式
-
Q3: 生成2个多个实例:
- A1:使用不同的ClassLoader加载单例的Class
- A2:使用反射生成不同的对象(class反射 | 构造函数反射)
- ps:代码SingleIns.main
原型模式 - meta (继承)
通过继承Cloneable实现深拷贝
- 暂时没有找到固定的通用模式
- 创建实例对象不经过构造函数,只是拷贝二进制码
builder: 生成器模式 - budiler
- @Builder lombok
推荐 - 主要是编程的模式
适配器模式-adapter (继承 | 组合)
将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作 设计的目的在于接口适配
- 对象适配器: 通过继承关系实现
- 类适配器: (代理模式中的代理人就是适配模式中期待的目标)
装饰着模式 - decorate (组合)
即委托模式, 注入; 委托:是代理执行,装饰:是功能扩展
外观模式 - Facade (组合)
代理模式 | 装饰代理, 子系统的多个接口委托给一个统一的委托类,对外提供一个统一的接口
- 一个代理的对象统一代理多个子类的执行
桥接模式 - bridge (组合)
抽象功能 与 实现功能分开, 通过注入重新组合
组合模式
不介绍
策略模式(继承 + 组合)
跟桥接基本一样
模版模式
不介绍
观察者模式 (组合: 被观察着 has 观察者)
分布式模式下,应用场景不大
迭代器模式
不介绍,java工具自动封装,使用迭代器自动分装
解释器模式
不介绍
访问者模式
不介绍
命令模式
备忘录模式
责任链模式(链式模式:本质是观察者模式) - chain
链式设计比责任链设计更加灵活
中介者模式
享元模式: Flyweight
状态模式
类之间关系
- has-a, 实例的属性
- use-a, 方法的入参
- is-a, 继承/实现