设计模式java语言实现(八)之代理模式

112 阅读5分钟

本文首发于java技术博客【码上】: jdkcb.com/

前言:

作者:韩数

Github:github.com/hanshuaikan…

个人技术博客:jdkcb.com/

本篇文章电子版和配套代码下载地址:github.com/hanshuaikan…

时间:2019-07-31

Jdk版本:1.8

代理模式定义:

为其他对象提供一种代理以控制对这个对象的访问。在面向对象中,有时候直接访问一些对象比较麻烦,所以代理模式就是在这个对象上加上一个访问该对象的访问层。类似于很多明星的事务实际都是交给经纪人处理的。

UML图:

代理模式UML图

角色分工:

  • 抽象主题角色:定义了被代理角色和代理角色的共同接口或者抽象类。
  • 被代理角色:实现或者继承抽象主题角色,定义实现具体业务逻辑的实现。
  • 代理角色:实现或者继承抽象主题角色,持有被代理角色的引用,控制和限制被代理角色的实现,并且拥有自己的处理方法(预处理和善后)

优/缺点:

优点:

  1. 职责清晰。
  2. 高扩展性。
  3. 智能化。

缺点:

  1. 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
  2. 实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

应用场景:

  1. 远程代理。
  2. 虚拟代理。
  3. Copy-on-Write 代理

在java中的应用:spring-aop实现,Mybatis 都有使用代理模式。

微剧场:

自从韩数荣登荣耀钻石宝座之后,前来拜师学艺的人络绎不绝,直接拉动了当地酒店行业的发展。

刚开始的时候还好,人毕竟来的不多,韩数把每个客人都安排妥当之后,仍然可以留一些时间去专注在自己的王者事业上,可是好久不长,奈何韩数王者技艺高超,方圆十里几乎无人不晓,渐渐地,找韩数的人越来越多,韩数不得不将大量的时间花在接待慕名前来的人们,导致自己在王者上投入的时间愈来愈少,韩数想长此以往下去,自己都没有时间打王者提升技艺了?核心竞争力一旦没有的话,那我岂不是要成为过气网红了?不能这样不能这样,我不要成为下一个乔碧萝。不!!!!

听说经纪公司给每一个明星都安排了一个经纪人,既然他们可以有的话,那么我为什么不能也雇一个呢?于是把阿呆叫过来做自己的经纪人。

每当有新的小迷妹过来拜访(咳咳,想什么呢?),阿呆负责把他们的生活起居安排好,包括酒店的预订,重要事情的通知等,当他们需要和韩数大神交流时直接通知韩数就行了。这样一来,韩数挤出来很多空闲的时间去提升自己的王者技巧,向无敌至上牛x轰轰荣耀王者的小目标又迈进了一步。

代码实战:

首先呢,我们声明一个明星接口,star,用来规范子类的行为。

public interface Star {
	//声明韩数与其他们交流王者上分技巧的方法
	public void exchange();
}

然后声明我们的具体实现HStar ,并实现Star接口,作为代表韩数的类。

public class HStar implements Star {

	@Override
	public void exchange() {
		System.out.println("巴拉巴拉嘤嘤嘤交流中....");
		
	}

}

同时我们创建一个代理类ProxyStar并实现Star接口,作为我们的经纪人角色。

public class ProxyStar implements Star{
	
	private  HStar star;

	@Override
	public void exchange() {
		if(star == null) {
			star = new HStar();
		}
		
		System.out.println("经纪人安排访客住宿,吃饭等等等等,通知韩数接待客人");
		star.exchange();	
		
	}

}

测试:

public class Test {
	
	public static void main(String[] args) {
		
		Star star = new ProxyStar();
		star.exchange();
		
	}

}

输出:

经纪人安排访客住宿,吃饭等等等等,通知韩数接待客人
巴拉巴拉嘤嘤嘤交流中....

不对,等等,好像哪里不对,我想想,就是那个,那个,就是.....

你是不是想说怎么看着那么像装饰者设计模式呢?其实呢,本例用装饰者模式实现的话代码其实是几乎一样的。

那,那他为什么叫代理模式呢?这不是挂羊头卖狗肉吗?还是之前计划的设计模式,发现凑不齐,硬加上去的?

当然不是这样,装饰者设计模式和代理模式虽然很相似,但是侧重点却不一样,下面让我们来看看他们的异同吧。

相同点:

  • 都需要实现同一个接口或者继承同一个抽象类,并且代理角色和装饰角色都持有被代理角色和构件角色的引用。
  • 两者都可以在被代理角色的业务方法前或者后添加额外的处理逻辑。

不同点:

  • 装饰器模式为了增强功能,而代理模式是为了加以控制。

大家可以把代理模式和装饰者模式看作是双胞胎两兄弟,只是发展侧重的点不一样,一个是侧重于对类功能上的增强,另一个则是侧重于对类的控制,正如我们前面所看到的,代理模式对于对象的操作几乎都是由代理对象来操作的。

总结:

代理模式分为动态代理和静态代理两种,本文所使用的代理模式均为静态代理,动态代理将作为本文的番外篇另作讲解。另外,本文相关实例代码和电子版markdown笔记文件已经上传至Github,有需要的朋友可以点击文首的链接下载,欢迎各位star,我是韩数,我们下篇文章再见!