最近在并发实践中,发现在具体的事件中,使用了一种java的设计模式:静态代理。想起来,代理模式的视频去年的暑假也有看过,但是那时候刚刚接触java,准确的说,是刚刚接触面向对象的编程,所以基本上什么都不懂。半年之后再看,有种苏卡斯乃的感觉。
Proxy Pattern:Provide a surrogate or placeholderfor another object to control access to it. --《DesignPatterns: Elements of Reusable Object-Oriented Software》
在《设计模式》中,对代理的定义如上:代理模式给某一个对象提供一个代理或者占位符,并由代理对象来控制对原对象的访问。看的半懂不懂,下面又例子具体说明。
所谓的代理,就是由A代表采取行动。例如我们去买火车票不一定要自己去火车站去买,可以到一些火车站代售点去买。再之于携程、去哪儿这样的第三方可以代理客户进行酒店、机票的预定行为。在实际的软件系统开发中,我们经常面临着对一个对象进行访问控制的问题。有些对象由于跨越网络或者安全方面等原因,不能直接或者不需要进行直接访问,直接访问的代价会给系统带来不必要的复杂性,比如可能要考虑访问延迟、运行效率低下等问题。如果在客户端程序和目标对象之间增加一层中间层,通过它来替代目标对象来完成客户程序对目标对象的各种操作要求,这样客户程序就可以透明地于目标程序进行交互。这时就需要用带代理模式。代理模式有静态代理和动态代理之分。先来简单的:静态代理。
抽象主题角色(Subject):真实对象和代理对象的公共接口,可以是抽象类,也可以是接口,是一个最普通的业务类型定义,无特殊要求。
真实角色(RealSubject):最终要引用的对象,也叫做被委托对象,被代理对象,是业务逻辑的具体执行者。
代理角色(Proxy):代理角色内部含有对真实角色的引用(在后续的代码中会有体现),从而可以操作真实对象,同时代理角色提供了与真实对象相同的接口以便在任何时刻都能代替真实对象,而且,代理对象可以在执行真实对象操作时,附加其他的操作(例如例子中的before()和after()),相当于对真实对象的封装。
实践出真知,代码即正义。下面就用具体的例子来说明一下静态代理的设计模式。
需求:新年到,天气好,大宝突发奇想寻思结个婚。于是找到了某教堂,要求其代理结婚典礼。这里,大宝就是真实角色(RealSubject),某教堂就是代理角色(Proxy)。
抽象主题角色(Subject)à( interface)Wedding.Java
package com.tree.thread;
public interface Wedding {
void merry();
}
Wedding.java
真实角色(RealSubject)àWeddingYou.java
package com.tree.thread;
//创建真实角色类
public class WeddingYou implements Wedding {
@Override
public void merry() {
// TODO Auto-generated method stub
System.out.println("You gotten merry");
}
}
WeddingYou.java
代理角色(Proxy)àWeddingProxy.java
package com.tree.thread;
//创建代理角色类
public class WeddingProxy implements Wedding {
private Wedding wed;
public WeddingProxy(Wedding wed){
this.wed = wed;
}
//添加业务逻辑
public void before(){
System.out.println("宣读誓言");
}
public void after(){
System.out.println("神父宣布成为合法夫妇");
}
@Override
public void merry() {
// TODO Auto-generated method stub
before();
System.out.println("交换戒指");
after();
}
}
测试(Test)àWeddingTest.java
package com.tree.thread;
//静态代理机制
//1.创建真实角色
//2.创建代理角色+真实角色的引用
//3.执行
public class WeddingTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建真实角色
Wedding man = new WeddingYou();
//创建代理角色+真实角色的引用
WeddingProxy you = new WeddingProxy(man);
//执行
you.merry();
}
}
运行测试类结果如下:
最后:新婚快乐~~~笑。