走穿java23种设计模式-6代理模式
代理模式,听过的人也是不多,但是根据它的名字你就可以想象到他的大概作用。代理就是它代你做一些事情!代码和应用理解起来也是不难的,本文就带你深入了解一下。
代理模式是java设计模式中三大类的第二类结构型模式。
代理模式现实场景
代理模式,理论上理解也是比较简单的,比如,你买车了,你要去办车牌,你可以自己去,也可以叫汽车销售公司代你去,但是你要把一些身份相关证明和一些表格填好給他们,他们代你去办理,其实相当于你自己办理,因为证件已经齐全了,他们就能办好了。这就是代理模式。还有网上抢票,因为你已经在他们的网站进行过验证,所有他们买票,就相当于你买票了,也是因为他们有你的身份信息和购买请求。
把你的信息給别人,别人帮你办事,这就是代理模式!
代理模式(Proxy Pattern)的定义
代理模式:为其他对象提供一种代理以控制这个对象的访问。
Proxy是代理的意思,Pattern是模式。
简单点理解就是把你的对象給代理者,代理者帮你做事。
代理模式的类图
代理模式涉及到的三种角色
1.抽象主题(Subject)角色
该角色是真实主题的代理主题的共同接口,以便在任何可以使用真实主题的地方可以使用代理主题。
2.真实主题(RealSubject)角色
该角色也叫委托角色或被代理角色,是业务逻辑的具体执行者。
3.代理主题(ProxySubject)角色
也叫委托类、代理类,该角色负责控制类对真实主题的引用,负责在需要的时候创建或删除真实主题对象,并且在真实主题角色处理完毕前后做预处理和善后工作。
上面的角色概念如果不理解,先看实例,返回来看就理解了。
从上面类图中可以看到代理主题是依赖于真实主题的,因为没有真实主题对象,代理主题是没事实际意义的。
代理模式的优点
1.职责清晰,真实角色只需要实现实际的业务逻辑,而不用关心其他非本职的事物。
比如,你知道买车牌要身份证和相关证件,但是去什么地方,需要跑多少路,排队要多久,你都不需要关心,代理人已经帮你去搞好了。
2.高扩展性
具体角色随需求不同可能有很多种,但是只要代理角色实现了接口,代理模式就完成可以在不做任何修改的情况下代理各种真实的主题角色。
上面一句话其实是说每个具体角色都会有一个抽象主题,但是代理模式可以有多个抽象主题,这个代理主题就可以給多个真实主题做事情。
3.代理模式的应用
代理模式其实在我们编程中是基本都会遇到的,比如很多网络框架,你传递給它一个参数对象Param,框架会从参数里面获取对象的数据,做很多其他的处理。
还有很多其他类似的框架也是要传入对象,然后,里面帮你做很多事情的。
还有我们也会传入一个对象到另一个类中,另一个类做很多判断,处理等等。
不管是别人的框架还是我们写的代码都是有很多代理模式相关的,只是我们没有意识到,看完本文后,你在以后的代码中多观察,是会发现很多这种需求的。
代理模式是一项基本的设计模式,许多比如状态模式、策略模式、访问者模式本质也是采用了代理模式。后面会給大家一一详解。
代理模式的实例
这里就以代理买车牌为示例
代理模式的实例类图
这里代理主题其实可以是还有很多操作方法,比如具体去哪里办车牌,給谁付钱等等步骤/方法,这里简化了。
各个接口/类的代码
1.抽象主题,IBuyCarNunber
定义购买车牌必须要的步骤方法
package p6_proxy;
/**
* 购买车牌的接口类
* 定义购买需要的相关手续
*/
public interface IBuyCarNunber {
public void carPlace(String city);//车牌的城市
public void validate();//验证购买者的身份
public void payMoney();//付钱
}
2.真实主题,实际要购买车牌者CarNumberBuyer
可以执行操作的有效对象
package p6_proxy;
/**
* 实际要购买车牌的人
* 如果自己购买是要经过下面几个具体步骤的
*/
public class CarNumberBuyer implements IBuyCarNunber {
String name;
public CarNumberBuyer(String name) {
this.name = name;
}
@Override
public void carPlace(String city) {
System.out.println("选择城市:" + city);
}
@Override
public void validate() {
System.out.println(name + "的有效证件");
}
@Override
public void payMoney() {
System.out.println(name + "支付1000元");
}
}
3.代理主题,,代理购买车牌者CarNumberProxy
package p6_proxy;
/**
* 购买车牌号的代理商
* 实际是通过购买人的对象类购买车牌
*/
public class CarNumberProxy implements IBuyCarNunber {
CarNumberBuyer carNumberBuyer;
/**
* 在构造方法种传入购买人的对象
* 后面的操作,代理人操作的方法,其实就是购买人自己操作
* 当然不用构造方法也是可以的,可以多写一个公开方法传入购买人的对象
*/
CarNumberProxy(CarNumberBuyer carNumberBuyer) {
this.carNumberBuyer = carNumberBuyer;
}
@Override
public void carPlace(String city) {
carNumberBuyer.carPlace(city);
}
@Override
public void validate() {
carNumberBuyer.validate();
}
@Override
public void payMoney() {
carNumberBuyer.payMoney();
}
}
4.代理模式的调用者ProxyDemo
package p6_proxy;
/**
* 代理模式的调用示例
*/
public class ProxyDemo {
public static void main(String[] args) {
CarNumberBuyer buyer = new CarNumberBuyer("李文");//创建购买人对象
CarNumberProxy proxy = new CarNumberProxy(buyer);//创建代理人对象,并把购买人对象传进去
proxy.carPlace("广东深圳");//代理人设置购买的车牌城市
proxy.validate();//代理人车牌人验证
proxy.payMoney();//代理人付钱
}
}
上面也是可以把代理模式中代理者的几个步骤封装在代理者对象的一个方法里面,这样你在外面看到代理者,只做一步就把你所有事情搞定了,看你需求吧。
看完上面的一个实际实例,有人可能会觉得我直接new一个实际操作对象,然后自己做那几步不就OK了吗,干嘛还要代理者和接口类,那么麻烦。这里也说明一下:这里只是一个简单的示例,如果真实主题有几十个步骤呢,而且判断很多呢,如果交给代理者可能只要看到几个步骤就可以完成了,并且逻辑可以处理得更加详细清晰。
到这里大家想必对代理模式有个比较清楚的认识了吧。
记住一句话,跟别人说就可以了:代理模式就是,把实际操作对象放到代理对象中,代理对象帮助实际对象做详细的处理。
当你你可以说详细点,代理模式就是代理对象类和实际对象类共同实现一个接口,接口定义了真实角色需要做一件事情必须步骤,然后创建代理对象的时候把真实对象传进去,这样就能实现代理者帮实际角色做很多判断和操作。
大家也可以看看,我之前写的几种模式的详解:
创建型模式详解:http://blog.csdn.net/wenzhi20102321/article/details/78175558
原型模式:http://blog.csdn.net/wenzhi20102321/article/details/78167984
建造者模式:http://blog.csdn.net/wenzhi20102321/article/details/78163855
抽象工厂模式:http://blog.csdn.net/wenzhi20102321/article/details/78153437
工厂方法模式:http://blog.csdn.net/wenzhi20102321/article/details/78129065
可以仔细对比一下工厂方法模式和抽象工厂模式,看看概念,看看类图,看看代码,就会明白了。
单例模式:http://blog.csdn.net/wenzhi20102321/article/details/77882203
java 23种设计模式介绍:http://blog.csdn.net/wenzhi20102321/article/details/54601909