装饰设计模式,代理设计模式 最通俗易懂的案例

 

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

interface 动物{
	public void eat();
	public void say();
}

class 狗 implements 动物{
	public void eat(){
		System.out.println("狗在吃..");
	}
	public void say(){
		System.out.println("狗在叫..");
	}
}


public class Demo01 {
	public static void main(String[] args) {
		
		//需求: 对狗类的say方法进行改造

		
		//方式1:继承
		class 继承狗 extends 狗{
			@Override
			public void say() {
				System.out.println("狗在汪汪汪汪的叫..");
			}
		}
		狗 dog = new 继承狗();
		dog.eat();
		dog.say();

		
		//方式2:装饰设计模式---用同类对象构造本类对象,从而对本类对象进行修复或增强。
		class 装饰狗{
			private 狗 dog;
			public 装饰狗(狗 dog) {
				this.dog = dog;
			}
			public void eat(){
				dog.eat();
			}
			public void say(){
				System.out.println("狗在汪汪汪汪的叫..");
			}
		}
		狗 dogx = new 狗();
		装饰狗 dog = new 装饰狗(dogx);
		dog.eat();
		dog.say();

		
		//方式3: 静态代理
		class 静态代理狗 implements 动物{
			private 动物 animal = null;
			public 静态代理狗(动物 ani) {
				this.animal = animal;
			}
			
			@Override
			public void eat() {
				animal.eat();//不需要改造,调用原有的方法
			}
		
			@Override
			public void say() {
				System.out.println("狗在汪汪汪汪的叫..");//需要改造
			}
		}
		狗 dogx = new 狗();
		静态代理狗 dog = new 静态代理狗(dogx);
		dog.eat();
		dog.say();
		/**
		 * 静态代理与装饰设计模式区别:
		 * 目的不同:
		 * 	装饰设计模式: 对原有类的方法进行扩展和增强,即可以改造原有类的方法,也可以通过装饰类给原有类增加新的方法.
		 * 	静态代理: 代理类实现原有类的接口,保证代理类拥有原有类的所有方法,目的是为了对原有类的方法进行改造.
		 * 
		 */

		
		//方式4: jdk动态代理
		final 狗 dog = new 狗();
		//创建jdk动态代理对象proxy
	         动物 proxy = Proxy.newProxyInstance(
			dog.getClass().getClassLoader(), //被代理对象的类加载器
			dog.getClass().getInterfaces(),  //被代理类实现的接口们
			new InvocationHandler() { //调用处理器
				*//**
				 * 代理对象调用任何方法时都会执行这个invoke方法
				 * porxy:代理对象
				 * method:代理对象当前正在调用的方法,当前正在被调用的方法是eat()和say()
				 * args:代理对象当前正在调用的方法的参数
				 *//*
				@Override
				public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
					if("say".equals(method.getName())){
						//如果当前被调用的是say方法,就进行改造
						System.out.println("狗在汪汪汪汪的叫...");
						return null;
					}else{
						//如果不是say方法,就使用被代理对象调用原有方法
						//此处的invoke(参数1,参数2)方法是Method类中的方法,参数1表示被代理对象,参数2表示当前被调用的方法的参数
						//method.invoke(dog, args)等价于dog.eat()
						return method.invoke(dog, args);
					}
				}
			});
		proxy.eat();
		proxy.say();

		
		//方式5: cglib动态代理
		
		//0.准备被代理对象
		final 狗 dog = new 狗();
		//1.创建增强器
		Enhancer enhancer = new Enhancer();
		//2.设定代理类需要实现的接口,如果没有接口需要实现,就不设置
		enhancer.setInterfaces(dog.getClass().getInterfaces());
		//3.设定代理类的父类 -- cglib基于继承实现动态代理,将被代理类作为父类传入
		enhancer.setSuperclass(狗.class);
		//4.设置回调函数
		enhancer.setCallback(new MethodInterceptor(){//方法拦截器
			/**
			 * 代理对象调用任何方法时都会执行这个intercept方法
			 * porxy:代理对象
			 * method:代理对象当前正在调用的方法,当前正在被调用的方法是eat()和say()
			 * args:代理对象当前正在调用的方法的参数
			 * mp: 
			 */
			@Override
			public Object intercept(Object proxy, Method method, Object[] args,MethodProxy mp) throws Throwable {
				if("say".equals(method.getName())){
					System.out.println("狗在汪汪汪汪的叫...");
					return null;
				}else{
					return method.invoke(dog, args);
				}
			}
		});
		//5.创建代理对象proxy
		狗 proxy = (狗) enhancer.create();
		proxy.eat();
		proxy.say();
	}
}

 

你可能感兴趣的:(装饰设计模式,代理设计模式 最通俗易懂的案例)