设计模式之-代理模式

基本概念

代理模式也称为委托模式,是一种结构性设计模式。
说到代理,可能大部分人都会有一种陌生又熟悉的感觉,日常生活中好像都能遇到,比如代理上网,招商代理,商务代理等;但又说不出个具体的一二三来;代理这个事情如果我们换个角度,从委托者的角色出发,我们找代理上网,是因为我们在访问某些网站时存在困难,需要有个角色来间接的帮我们实现这个功能;我们找商务代理,可能是因为许多事我们不在行或者其他原因,需要找专业的中间人来帮我们做事。因此,日常生活中我们更多扮演的是委托人的角色,代理以一种中间人的角色,帮我们是处理我们无能为力的事情。
如果从写代码的角度出发,当我们遇到以下场景:

  • 无法直接访问某个对象
  • 不想直接访问某个对象
  • 访问某个对象存在困难

的时候,我们就可以通过一个代理,通过它来间接访问真正的对象。

应用

代理模式非常简洁,总共就三个角色,包括抽象主题委托者代理者

1
2
3
4
5
6
7
8
9
10
11
12
package com.github.feifuzeng.designpattern.proxy;

/**
* @author feifz
* @version 1.0.0
* @Description 抽象主题
* @createTime 2019年06月25日 15:11:00
*/
public interface Subject {

void doSomething();
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.github.feifuzeng.designpattern.proxy;

/**
* @author feifz
* @version 1.0.0
* @Description 真正实现的主题类
* @createTime 2019年06月25日 15:11:00
*/
public class RealSubject implements Subject{
@Override
public void doSomething() {
System.out.println("This is real doSomeThing");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.github.feifuzeng.designpattern.proxy;

/**
* @author feifz
* @version 1.0.0
* @Description 代理主题
* @createTime 2019年06月25日 15:12:00
*/
public class ProxySubject implements Subject {

private Subject mSubject;
/** 代理类持有委托类的引用*/
public ProxySubject(Subject realSubject) {
mSubject = realSubject;
}

@Override
public void doSomething() {
mSubject.doSomething();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.github.feifuzeng.designpattern.proxy;

/**
* @author feifz
* @version 1.0.0
* @Description 客户端
* @createTime 2019年06月25日 15:13:00
*/
public class Client {
public static void main(String[] args) {
/** 创建委托类*/
Subject mRealSubject=new RealSubject();
/** 创建代理类*/
ProxySubject mProxy = new ProxySubject(mRealSubject);
/** 由代理类去做具体的操作*/
mProxy.doSomething();
}

}

可以看到RealSubject和ProxySubject都实现了接口Subject。在客户端使用ProxySubject的实例调用doSomething方法,而不是使用RealSubject的实例来实现。
你可能会好奇,这么做的意义是什么呢?直接用RealSubject的实例来调用doSomething方法不也可以吗?何必多此一举。试想,如果现在有很多个委托类,他们各自的实现都不同,客户端只关心doSomething 的调用,而不关心具体的实现,这样代理类就可以在其内部屏蔽委托类之间的差异了,这也是客户端不想关注的事情。

参考