Java设计模式总纲及面试必问的几种模式

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之间转换


最后贴一张设计模式之间关系图:


猜你喜欢

转载自blog.csdn.net/qq_41360177/article/details/88726367