Java设计模式类型总结:
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式
-------------------------------- 一共23种设计模式 -----------------------
单例模式:
单例保证一个对象JVM中只能有一个实例,常见单例 懒汉式、饿汉式
--懒汉式,就是需要的才会去实例化,线程不安全。
--饿汉式,就是当class文件被加载的时候,初始化,天生线程安全。
----------- 手撕代码,要求必须会 ---------
懒汉式:
public class Singleton{
//定义成员变量
private static Singleton singleton;
//默认构造器
private Singleton(){}
//使用双重检验锁判断该对象是否被创建
public static Singleton getSingleton(){
if(singleton = null){
synchronized(Singleton.class){
if(singleton = null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
饿汉式:
public class Singleton{
//定义在初始化时就加载该对象 -static只初始化一次
private static Singleton singleton = new Singleton();
//定义构造器
private Singleton(){}
//定义外部可获取该对象的方法
public Singleton getSingleton(){
return singleton;
}
}
代理模式:
说明:
通过代理控制对象的访问,可以详细访问某个对象的方法,在这个方法调用处理,或调用后处理 --简单理解为中介
场景:
安全代理 可以屏蔽真实角色
远程代理 远程调用代理类RMI
延迟加载 先加载轻量级代理类,真正需要在加载真实
分类:
静态代理(静态定义代理类) --原始方式,需要对每一个真实对象进行代理并创建代理类去实现,实现机制不适用。
动态代理(动态生成代理类) --重点使用
Jdk自带动态代理
Cglib 、javaassist(字节码操作库)
JDK代理方式:
1.首先实现接口InvocationHandler,在方法invoke里卖弄定义要代理的事务
public class JDKProxy implements InvocationHandler {
private Object tarjet;
public JDKProxy(Object tarjet) {
this.tarjet = tarjet;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("我是中介,开始做点什么");
Object oj = method.invoke(tarjet, args);
System.out.println("我是中介,做完了");
return oj;
}
}
2.使用该动态代理时需要使用反射机制实现匿名代理类
XiaoMing xiaoMing = new XiaoMing();
JDKProxy jdkProxy = new JDKProxy(xiaoMing);
Proxy.newProxyInstance(xiaoMing.getClass().getClassLoader(),xiaoMing.getClass().getInterfaes(), jdkProxy).方法();
CGLIB动态代理:需要导包:asm、cglib
1.实现接口MethodInterceptor
public class Cglib implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("我是中介,开始做些什么");
Object invokeSuper = methodProxy.invokeSuper(o, args);
System.out.println("我是中介,结束");
return invokeSuper;
}
}
2.实现该动态代理,使用asm开源包的代理类
Cglib cglib = new Cglib();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(XiaoMing.class);
enhancer.setCallback(cglib);
enhancer.create().方法();
俩大动态代理的区别:
JDK动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP
3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换
最后贴一张设计模式之间关系图: