代理模式是一种结构型模式,为其他对象提供一种代理以控制对这个对象的访问。
每个公司都有老板,但是老板并不是所有人都能见到,以及不是所有人都能让老板做事。而有一个秘书,主要负责的就是和老板对接,如果有什么会议需要先联系秘书,然后秘书转告老板。而这个秘书可以理解为就是代理。
Person是对代理者与被代理者的抽象,让代理者与被代理者具有一致性,同时Person中定义了审批重要文件以及和几个部门负责人开会的接口。而CEO和SeretaryProxy都实现于Person,SeretaryProxy就是秘书,是CEO的代理。
Person是规定代理者和被代理者的一致性,同时定义了两个抽象类分别是审批重要文件以及和几个重要负责人开会。
public interface Person {
/**
* 审批重要文件
*/
void approve();
/**
* 开会
*/
void haveAMeeting();
}
CEO实现于Person,对于实现的方法只是做了简单的输出打印。而构造方法定义为protected的原因是只想让代理去找到他,而不能通过其他的方式去联系CEO,所以代理者应该和CEO在同包下,而调用者应该去调用代理者。
public class CEO implements Person{
protected CEO() {
}
@Override
public void approve() {
System.out.println("审批重要的文件。。。");
}
@Override
public void haveAMeeting() {
System.out.println("和几个部门负责人开会。。。");
}
}
SecretaryProxy就是秘书,实际上有些工作自己能做就可以选择自己做,但是对于开会以及审批重要文件来说,自己不能处理,所以需要CEO来进行处理,同时可以在代理的前后做一些自己的处理。
例如:如果是做登录,可以在代理前做一些密码是否是中文检验。或者是否为空等校验,而实际的登录则是通过代理来处理。
public class SecretaryProxy implements Person{
private Person person;
/**
* 秘书类中进行代理CEO
*/
public SecretaryProxy() {
person = new CEO();
}
/**
* 通过代理,来让ceo审批文件
*/
@Override
public void approve() {
System.out.println("代理者通知CEO审批文件");
person.approve();
}
/**
* 通过代理,来让ceo开会
*/
@Override
public void haveAMeeting() {
System.out.println("代理者通知CEO开会");
person.haveAMeeting();
}
}
实际使用的时候可以发现,我们操作的只是代理,要审批文件以及要开会都是找的代理,而不是CEO,至于秘书要不要找CEO调用者根本不需要关心。代理如果能自己处理就自己处理,不能就交给CEO来做。
实际上实例代码中的的CEO的产生,是在调用SecretaryProxy的构造方法时产生的,这样就写死了,但是我们可以传入一个被代理者这样就能解决这个问题。
public class Test {
public static void main(String[] args) {
Person secretaryProxy = new SecretaryProxy();
secretaryProxy.approve();
secretaryProxy.haveAMeeting();
}
}
代理者通知CEO审批文件
审批重要的文件。。。
代理者通知CEO开会
和几个部门负责人开会。。。
代理模式中的角色
Subject(主体),规定代理者和被代理者的一致性,在文中由Person类扮演此角色。
Proxy(代理人),对事情能自己处理的自己处理,只有自己处理不来了的时候才会找真实的人做处理。在文中由SecretaryProxy类扮演此角色。
RealSubject(实际的主体),是对Subject进行实现的,同时相当于被代理者。在文中由CEO类扮演此角色。
Client(调用者),是对代理进行访问的角色,文中由Test类扮演此角色。
代理模式是能自己做自己做,不能做的时候才交给真实者来处理,而适配器更偏向于对原始接口的一个复用,在不改变原始接口的情况下进行使用。
装饰者模式更注重于对于功能的增强。而代理更加注重委托,同时被代理者只能被代理者进行访问。
参考文献《图解设计模式》
代码获取地址:https://gitee.com/bughong/design-pattern