博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式系列--Proxy
阅读量:6610 次
发布时间:2019-06-24

本文共 4130 字,大约阅读时间需要 13 分钟。

hot3.png

一.类图

 

二.意图

为其他对象提供一种代理以控制对这个对象的访问。

三.适用性

a) 在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用Proxy 模式。下面是一 些可以使用Proxy 模式常见情况:

1. 远程代理(Remote Proxy )为一个对象在不同的地址空间提供局部代表。
2. 虚代理(Virtual Proxy )根据需要创建开销很大的对象。在动机一节描述的ImageProxy 就是这样一种代理的例子。
3. 保护代理(Protection Proxy )控制对原始对象的访问。保护代理用于对象应该有不同 的访问权限的时候。
4. 智能指引(Smart Reference )取代了简单的指针,它在访问对象时执行一些附加操作。 

b) 它的典型用途包括:

i. 对指向实际对象的引用计数,这样当该对象没有引用时,可以自动释放它

ii. 当第一次引用一个持久对象时,将它装入内存。

iii. 在访问一个实际对象前,检查是否已经锁定了它,以确保其他对象不能改变它。

四.实例

考研代理本来是我最讨厌的一类人之一,但是今天不得不拿这个例子出来讲一下。对于要考研的人来说,考研代理无疑为他们提供了方便,只要在他这里报名交钱就行了,其他的事情由他为自己安排。

package explore.proxy; public interface TrainOrgnization {
public void register(); } package explore.proxy; public class LingHangOrgnization implements TrainOrgnization {
@Override public void register() {
System.out.println("欢迎报名领航,祝您考试成功!!"); } } package explore.proxy; public class HaiTianOrgnization implements TrainOrgnization {
@Override public void register() {
System.out.println("欢迎报名海天,祝您考试成功!"); } } package explore.proxy; public class StudentProxy {
protected TrainOrgnization orgz; public StudentProxy(TrainOrgnization orgz) {
this.orgz = orgz; } } package explore.proxy; import java.util.Random; public class StuentOfLingHangProxy extends StudentProxy implements TrainOrgnization {
public StuentOfLingHangProxy(LingHangOrgnization orgz) {
super(orgz); } //选取座位号 public void chooseSeatNum() {
System.out.println("您的座位号:" + Math.abs(new Random().nextInt())); } //打印收据 public void printCheck() {
System.out.println("您的收据"); } @Override public void register() {
printCheck(); chooseSeatNum(); orgz.register(); } } package explore.proxy; import java.util.Random; public class StuentOfHaiTianProxy extends StudentProxy implements TrainOrgnization {
public StuentOfHaiTianProxy(HaiTianOrgnization org) {
super(org); } // 选取座位号 public void chooseSeatNum() {
System.out.println("您的座位号:" + Math.abs(new Random().nextInt())); } // 打印收据 public void printCheck() {
System.out.println("您的收据"); } @Override public void register() {
printCheck(); chooseSeatNum(); orgz.register(); } } package explore.proxy; public class Client {
public static void main(String[] args) {
StuentOfLingHangProxy lhProxy = new StuentOfLingHangProxy(new LingHangOrgnization()); StuentOfHaiTianProxy htProxy = new StuentOfHaiTianProxy(new HaiTianOrgnization()); //报名领航 lhProxy.register(); //报名海天 htProxy.register(); } }

上面展示的是静态代理的形式,每一个类对应一个代理类,这样实现起来可能比较麻烦。所以JDK同时提供了动态代理的实现具体的类是InvocationHandlerProxy

相对于上面的例子两个考研机构不变,但是多了一个代理工厂控制类,动态生成代理类:

package explore.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class ProxyFactory implements InvocationHandler {
private TrainOrgnization proxied; public ProxyFactory(TrainOrgnization proxied) {
this.proxied = proxied; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理类: " + proxy.getClass() + ", method: " + method); return method.invoke(proxied, args); } } package explore.dynamicproxy; import java.lang.reflect.Proxy; import java.util.Random; public class Client {
// 选取座位号 public void chooseSeatNum() {
System.out.println("您的座位号:" + Math.abs(new Random().nextInt())); } // 打印收据 public void printCheck() {
System.out.println("您的收据"); } public void register(TrainOrgnization orgz) {
chooseSeatNum(); printCheck(); orgz.register(); } public static void main(String[] args) {
HaiTianOrgnization real = new HaiTianOrgnization(); TrainOrgnization proxy = (TrainOrgnization) Proxy.newProxyInstance( TrainOrgnization.class.getClassLoader(), new Class[] { TrainOrgnization.class }, new ProxyFactory(real)); new Client().register(proxy); } }

转载于:https://my.oschina.net/u/197668/blog/361198

你可能感兴趣的文章
3 Oracle 32位客户端安装及arcgis连接
查看>>
Perl完全自学手册图文教程
查看>>
阿里云API网关使用教程
查看>>
git常用命令记录(持续更新)
查看>>
《CSS揭秘》笔记
查看>>
如何让pm2支持es6
查看>>
Android 官方兼容库 EmojiCompat Support Library
查看>>
QPM 准备优化前的思考
查看>>
react-router的基本原理
查看>>
MobX 状态管理
查看>>
广州牵引力讲述java开发师怎样规划职业发展比较好?
查看>>
Vue.js 第二天: 表单输入绑定
查看>>
windows下使用nginx调试简介
查看>>
JavaScript高级程序设计(第3版)手写第一天。2019年2月23日,星期六
查看>>
RxJava2:Observable和Observer如何传递
查看>>
《Java编程思想》读书笔记-类与对象
查看>>
刷前端面经笔记(八)
查看>>
力扣(LeetCode)46
查看>>
【Android】Retrofit 2.0 的使用
查看>>
教程:gif动画播放与制作
查看>>