注:初学设计模式,如果有错误希望能多多指教(Thanks >-<)
代理模式的介绍(该篇主要讲解静态代理模式)
代理模式定义为:为其他对象提供一种代理以控制对这个对象的访问(相当于与中间人)。是结构设计型模式中的一种。
代理模式的参与角色
参与的角色 | 角色的功能 |
---|---|
抽象角色 | 该角色是代理角色和委托角色(被代理角色)的共同接口,主要包含了被代理角色的实现方法 |
代理角色 | 实现了抽象角色,在内部持有一个委托角色的引用,该类通过和委托类共同实现一个接口来达到代替委托类的目的 |
委托角色 | 也可以叫做被代理角色,该角色实现所要实现的业务逻辑,可以供代理类调用 |
代理模式的UML
代理模式的案例(静态)
在介绍案例之前,先大致讲一下代理模式的三个种类:
(1)静态代理模式:在程序运行之前代理角色和委托角色的关系就已经确定了,代理角色和委托角色一起实现了抽象接口,通过调用代理角色的方法来调用对应的委托角色的接口。
(2)动态代理模式:在实现阶段不需要关心代理类,在运行阶段才指定对象,在动态内存中构建代理类。
详细请见:10分钟看懂动态代理设计模式
(3)Cglib代理模式:略,有兴趣的小伙伴可以自行上网查询相关的内容。
静态代理模式的案例:继续前面几篇的案例(不看该篇前面几篇设计模式的案例也可以看懂),小明在网上选啊选,终于他买了一个粉色的保温杯,过了几天,周末小明的快递保温杯到了,但是小明正巧周末回家了,而他的室友还有在寝室,所以他决定然他的室友代替他去拿快递。现在使用代理模式来实现这个功能。静态代理模式的设计:首先设计一个抽象角色(拿快递——这个功能是根据委托角色小明需要具体事项的功能来设计),委托角色(该案例中委托角色是小明,该委托角色需要实现抽象角色拿快递的功能)以及代理角色(代理小明这个委托者去拿快递的室友,同样实现了抽象角色中拿快递的功能,因为本身就是代理者,代理委托角色实现功能的角色)。所有角色代码如下:
(1)抽象角色
/**
* @Introduction 该类是一个抽象角色,是一个抽象类,其中所需要的方法是根据委托角色具体需要实现的功能来确定
*/
public abstract class TakeExpress {
/**该抽象方法是拿快递*/
public abstract void takeExpress();
}
(2)委托角色(被代理的角色)
/**
* @Introduction 该类是一个委托角色类,该类继承了抽象角色类TakeExpress,是需要被代理的类
*/
public class Entrustor extends TakeExpress{
private String name;
/**构造方法,赋予委托者名字:小明*/
public Entrustor(String nam){
this.name=nam;
}
/**重写TakeExpress类中的方法*/
@Override
public void takeExpress(){
System.out.println("拿快递");
}
}
(3)代理角色(帮委托者实现功能的角色)
/**
* @Introduction 该类是一个代理类,作为代理角色,同样继承了TakeExpress类的功能,并且
* 在该类内部持有有一个委托者对象,用于在外部调用的时候,通过该代理类可以间接
* 调用到委托者类(真正的业务逻辑功能实现类)
*/
public class Proxy extends TakeExpress{
private Entrustor xiaoming;//一个委托角色对象,该对象是真正实现业务逻辑的对象
/**构造方法*/
public Proxy(){
xiaoming=new Entrustor("小明");
}
/**重写了方法,在该方法的内部调用了委托者的方法*/
@Override
public void takeExpress() {
System.out.print("帮小明");
this.xiaoming.takeExpress();
}
}
(4)模拟用户界面逻辑代码
/**
* @Introduction 该类模拟用户界面逻辑代码块
*/
public class Main {
public static void main(String[] args){
Proxy shiyou=new Proxy();
shiyou.takeExpress();
}
}
案例分析
在这个案例中,我们使用到了三种角色,但是最后在模拟用户界面逻辑代码时我们只需要使用一个代理角色来完成该拿快递的功能。下面我来问一下:首先我是一个服务器访问者向访问一个服务器,然后中间有一个代理层它帮助我去访问这个服务器,并且返回一些相关信息给我,请问我这个服务器访问者是委托者(被代理者)还是服务器是委托者?答案是服务器是委托者(或者说被代理者),希望你们不要因为我的案例误导了你们委托者的概念,委托者你可以记成被代理者,其的功能是放在代理者中实现的,在刚刚服务器的例子中,很明显,代理层是帮助我这个访问者来实现访问服务器的功能,它将服务器的功能放在它自己内部进行调用,并且返回一些信息给我。
在上服务器的案例中(由于上面代码案例不好描述),我们可以发现服务器只需要是做好自己该做的功能,它不需要考虑会有谁来使用它,而对于我这个访问者来说我也不需要考虑我怎么去使用服务器,这些工作交给中间层去实现。
代理模式的优缺点(静态代理模式)
优点:
(1)在客户端,不需要具体怎么做,它只需要使用代理角色就行,这样降低了耦合性。
(2)就是上面分析中所提到的委托角色只需要考虑自己的功能怎么实现如何实现最好,不需要考虑其他的东西。(有代理层可以辅助完成)——保证代码的复用性
(3)可以将代码中公共的部分有代理角色来完成,实现了业务的分工合作。
缺点:
(1)同样有代理角色造成(成也是它败也是它),由于增加了代理角色,这样会使的程序的性能有所下降(每一个请求都需要创建一个代理对象)
(2)由于代理角色和委托角色实现了同样的接口,如果委抽象角色要增加相应的功能,然后对应所有代理角色和委托角色也需要增加相应的功能。
(3)一个代理只能为一个对象进行代理,如有多个委托就需要创建多个代理,扩大了程序大规模,如果程序的规模比较大时,静态代理模式就无法胜任了。