代理模式的介绍
代理模式也称为委托模式,在开发中经常用到,是编程的好帮手,在日常生活中也比较常见。比如公司中午让同事帮忙带一份饭,比如我们请一个律师打官司,比如我们用代理服务器上网等等。代理模式真是无处不在。
代理模式的定义
为其它对象提供一种代理以控制对这个对象的访问。
代理模式的使用场景
当无法或者不想直接访问某个对象或者访问某个对象存在困难时,可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象或者代理对象需要实现相同的接口。
代理模式一般的写法(静态代理模式): 代理类和被代理类共同的一个接口:
/**
*
* 抽象角色
*
* 该类的主要职责是声明真实主题与代理的共同接口方法
* 该类既可以是一个抽象类也可以是一个接口
*
*/
public abstract class Subject {
public abstract void visit();
}
一个真实的角色,也就是被代理类:
/**
* 真实角色
*
* 该类也称为被委托类或被代理类,该类定义了代理所表示的真实对象
* 由其执行具体的业务逻辑方法,而客户类则通过代理类间接地调用真实主题类中定义的方法
*
*/
public class RealSubject extends Subject{
@Override
public void visit() {
}
}
实现一个代理类:
/**
*
* 代理类
* 委托对象与代理对象需要实现相同的接口
* 该类也被称为委托类或者代理类,该类持有一个对真实主题的类的引用
* 在其所实现的接口方法中调用真实主题类中相应的接口方法执行,以此起到代理的作用
*
*
*/
public class ProxySubject extends Subject{
Subject realSubject = null;
public ProxySubject(Subject realSubject){
this.realSubject = realSubject;
}
@Override
public void visit() {
preRequest(); //真实角色前
realSubject.visit();
postRequest(); //真实角色后
}
private void preRequest(){
}
private void postRequest(){
}
}
客户端测试类:
/**
*
* 客户类,即使用代理类的类型
*/
public class ProxyTest {
public static void test(){
//构造一个真实对象
Subject realSubject = new RealSubject();
//通过一个真实对象构造一个代理对象
Subject proxy = new ProxySubject(realSubject);
//调用代理对象的相关方法
proxy.visit();
}
}
上面是静态代理模式的一般实现流程,我们今天讲的都是静态代理模式。
上面的流程不够真实,我们来举一个更具体的例子,比如生活中的打官司。
小明是某一个公司的员工,老板欠了小明半年的工资,无奈之下,小明请了一个律师将老板告上了法庭
首先,需要有一个抽象的接口:
/**
* 诉讼接口类
* 4个方法很简单,诉讼的一般流程
*/
public interface ILawsuit {
//提交申请
void submit();
//进行举证
void burden();
//开始辨护
void defend();
//诉讼完成
void finish();
}
需要有一个小明:
/**
* 被代理者,小明
*/
public class XiaoMin implements ILawsuit{
@Override
public void submit() {
//老板欠小明一个月工资,小明只好申请仲裁
System.out.println("老板拖欠工资,特此申请仲裁");
}
@Override
public void burden() {
//小明证明充分,不怕告不赢
System.out.println("这是合同和过去一年的银行流水");
}
@Override
public void defend() {
//铁证如山,辩护也没有什么好说的
System.out.println("证据充分,不用再说什么了");
}
@Override
public void finish() {
//结果也是肯定的,必赢
System.out.println("诉讼成功,判决老板即日起七天内结算工资");
}
}
需要有一个代理律师来代理小明打官司
/**
* 代理律师
*/
public class Lawyer implements ILawsuit{
//持有一个具体的被代理者的引用
private ILawsuit mLawsuit;
public Lawyer(ILawsuit lawsuit){
mLawsuit = lawsuit;
}
@Override
public void submit() {
mLawsuit.submit();
}
@Override
public void burden() {
mLawsuit.burden();
}
@Override
public void defend() {
mLawsuit.defend();
}
@Override
public void finish() {
mLawsuit.finish();
}
}
客户端怎么用呢?下面是客户端类:
/**
* 客户端类
*/
public class Client {
public static void main(String[] args){
//构造一个小明
ILawsuit xiaomin = new XiaoMin();
//构造一个律师并将小明作为构造参数传递进去
ILawsuit lawyer = new Lawyer(xiaomin);
//律师提交诉讼
lawyer.submit();
//律师进行举证
lawyer.burden();
//律师代替小明进行辩护
lawyer.defend();
//完成诉讼
lawyer.finish();
}
}
运行结果如下:
老板拖欠工资,特此申请仲裁
这是合同和过去一年的银行流水
证据充分,不用再说什么了
诉讼成功,判决老板即日起七天内结算工资
使用就是这么简单