23种设计模式#【代码示例】代理设计模式(静态&动态实现)

代理可以理解为替代代理者完成的一些任务,可能是变的、可能需要一些专业知识、可能需要一些特定的资源…总之,这些任务,被代理者自己处理会很麻烦,那么我们就交给代理者完成。比如,拿生活中我们买房子的例子,一般买房子我们一般会找中介,中介能到了什么样的作用?资金监管、解读购房政策,因为更专业、拥有更丰富的资源、明白购房的手续等等,所以中介这个角色起到了至关重要的作用。同样在Java中,在执行某些类的方法之前,我们也要做这样的一些事情:事物的开启与提交、权限的验证、日志的打印、时间的统计…这些事情不属于我们项目的业务逻辑部分,因为他们多变、繁琐、覆盖面广…不适合每一个类的每一个方法对应的添加。这样一说是不是更好的理解了?

1.什么是代理模式?

   静态代理类只能替一个主题接口进行代理工作。如果主题接口不同,代理工作相同,也需要编写两个代理类。

  (1)被代理者,主要负责业务逻辑

  (2)代理者,类似后勤保障的

  (3)主题:类似接口(需要实现)

2.静态代理模式

  (1)被代理者,主要负责业务逻辑

  (2)代理者,手动编写一个代理类

  (3)主题:类似接口(需要实现)

  优点:代码简洁、容易理解 缺点:代码冗余(多个主题接口)

代码演示1:
package com.conding0110lin.example;
/*代理设计模式*/
public class AgencyTest {
	public static void main(String[] args) {
		/*House house = new Agency();//多态引用
		house.buy();*/
		//中介会代理顾客做一些繁琐的业务事情。
		//(中介)验证房源是否合法、有效、尾款处理...
	
		House house = new Agency(new Customer());//多态引用--两次向上转型
		house.buy();
		/*中介会代理顾客做一些繁琐的业务事情。
		(中介)验证房源是否合法、有效、尾款处理...
		顾客需要自己交钱、签合同、拿钥匙...(核心事情)*/
	}
}

//主题接口(实现的功能)
interface House{
	void buy();
	
}
//被代理者(顾客)
class Customer implements House{

	@Override
	public void buy() {
		//核心的事情由自己去做,非核心的事情由代理(中介)去做
		System.out.println("顾客需要自己交钱、签合同、拿钥匙...(核心事情)");
	}	
}
//代理者(中介)
class Agency implements House{
	private House target;
	
	public Agency(House target) {
		super();
		this.target = target;
	}
	@Override
	public void buy() {
		System.out.println("中介会代理顾客做一些繁琐的业务事情。");
		System.out.println("(中介)验证房源是否合法、有效、尾款处理...");
		target.buy();//被代理者(顾客)处理的核心事情
	}
}

   ☞思考:现在被代理者(顾客)不仅仅是买房子的,还有租房子的,意思就是被代理者(顾客)不止一个了,这里解决的方式之一就是需要再写一个代理类(中介)【为租房子的主题接口编写一个代理类】。想想在我们实际生活中,不管是顾客租房子还是买房子,一个中介就能同时满足多个顾客的需求,所以在Java设计模式中,两个主题接口,代理者应该一个就能解决。显然这种静态设计模式实现就比较麻烦,接下里就会采用动态设计模式进行实现。

3.动态代理模式

  (1)被代理者,主要负责业务逻辑

  (2)不直接编写代理类,编写一个叫做代理工作处理器的类

代理工作处理器必须实现一个java.lang.reflect.InvocationHandler接口

  (3)主题:类似接口(需要实现)

  (4)动态的创建代理类或代理类的对象

java.lang.reflect .Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。

引用JDK_API_1.6

在这里插入图片描述

代码演示2:
package com.conding0110lin.example;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*代理设计模式*/
public class AgencyTest {
	public static void main(String[] args) {
		// (1)创建被代理者对象(买房子顾客)
		Customer buyCustomer = new Customer();

		//(2)获取被代理者的类加载器
		ClassLoader loader = buyCustomer.getClass().getClassLoader();
		//(3)获取被代理者的实现的实现的接口们
		Class<?>[] interfaces = buyCustomer.getClass().getInterfaces();
		//(4)创建代理工作处理器对象
		Handler h =new Handler(buyCustomer);
		/**
		 * public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,  InvocationHandler h)
		 * 参数1:表示被代理者的类加载器
		 * 参数2:被代理者实现的接口们
		 * 参数3:代理者要替被代理者,做的代理工作处理器对象        
		 */
		Object proxy = Proxy.newProxyInstance(loader, interfaces, h);
		BuyHouse buyHouse = (BuyHouse)proxy;
		buyHouse.buy();
	/*	中介会代理顾客做一些繁琐的业务事情。
		(中介)验证房源是否合法、有效、尾款处理...
		买房子顾客需要自己交钱、签合同、拿钥匙...(核心事情)*/
		
		Renter renter = new Renter();
		ClassLoader loader2 = renter.getClass().getClassLoader();
		Class<?>[] interfaces2 = renter.getClass().getInterfaces();
		Handler h2 =new Handler(renter);
		Object proxy2 = Proxy.newProxyInstance(loader2, interfaces2, h2);
		RentHouse rentHouse = (RentHouse)proxy2;
		rentHouse.buy();
		
	/*	中介会代理顾客做一些繁琐的业务事情。
		(中介)验证房源是否合法、有效、尾款处理...
		租房子顾客需要自己交钱、选房、配钥匙...(核心事情)*/
	}
}

// 主题接口(实现的功能)
interface BuyHouse {
	void buy();

}

interface RentHouse {
	void buy();

}

// 被代理者(买房子顾客)
class Customer implements BuyHouse {

	@Override
	public void buy() {
		// 核心的事情由自己去做,非核心的事情由代理(中介)去做
		System.out.println("买房子顾客需要自己交钱、签合同、拿钥匙...(核心事情)");
	}
}

// 被代理者(租房子顾客)
class Renter implements RentHouse {

	@Override
	public void buy() {
		// 核心的事情由自己去做,非核心的事情由代理(中介)去做
		System.out.println("租房子顾客需要自己交钱、选房、配钥匙...(核心事情)");
	}
}
//代理工作器-无固定为哪个主题接口的实现类代理
class Handler implements InvocationHandler {
	private Object target;

	public Handler(Object target) {
		super();
		this.target = target;
	}

	/*
	 * 此方法体: 
	 * (1)代理工作的代码 
	 * (2)被代理者调用自己的核心逻辑方法
	 * 形参一:proxy 表示代理类的对象 
	 * 形参二:method 表示被代理者真正要代用的方法
	 *  形参三:args 表示method方法执行时需要的实参
	 * Method类object invoke(object obj ,object...args) obj调用方法的对象,args表示方法的实参列表
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("中介会代理顾客做一些繁琐的业务事情。");
		System.out.println("(中介)验证房源是否合法、有效、尾款处理...");
		Object returnvalue = method.invoke(target, args);
		return returnvalue;
	}
}

推荐阅读往期博文:

23种设计模式#【代码示例】工厂设计模式(反射&方法实现)

23种设计模式#【代码示例】单例设计模式(饿汉&懒汉|加锁&双重检查&静态内部类)

#轻松一刻

在这里插入图片描述


  ☝上述分享来源个人总结,如果分享对您有帮忙,希望您积极转载;如果您有不同的见解,希望您积极留言,让我们一起探讨,您的鼓励将是我前进道路上一份助力,非常感谢!我会不定时更新相关技术动态,同时我也会不断完善自己,提升技术,希望与君同成长同进步!

☞本人博客:https://coding0110lin.blog.csdn.net/  欢迎转载,一起技术交流吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值