代理模式
来源:互联网 发布:死是什么感觉 知乎 编辑:程序博客网 时间:2024/06/04 20:12
1、为什么要使用代理模式?
原因一:你可能在外地上班,买房子的人没法找到你直接交易。
对应到我们程序设计的时候就是:客户端无法直接操作实际对象。那么为什么无法直接操作?一种情况是你需要调用的对象在另外一台机器上,你需要跨越网络才能访问,如果让你直接coding去调用,你需要处理网络连接、处理打包、解包等等非常复杂的步骤,所以为了简化客户端的处理,我们使用代理模式,在客户端建立一个远程对象的代理,客户端就象调用本地对象一样调用该代理,再由代理去跟实际对象联系,对于客户端来说可能根本没有感觉到调用的东西在网络另外一端,这实际上就是Web Service的工作原理。另一种情况虽然你所要调用的对象就在本地,但是由于调用非常耗时,你怕影响你正常的操作,所以特意找个代理来处理这种耗时情况,一个最容易理解的就是Word里面装了很大一张图片,在word被打开的时候我们肯定要加载里面的内容一起打开,但是如果等加载完这个大图片再打开Word用户等得可能早已经跳脚了,所以我们可以为这个图片设置一个代理,让代理慢慢打开这个图片而不影响Word本来的打开的功能。申明一下我只是猜可能Word是这么做的,具体到底怎么做的,俺也不知道。
原因二:你不知道怎么办过户手续,或者说除了你现在会干的事情外,还需要做其他的事情才能达成目的。
对应到我们程序设计的时候就是:除了当前类能够提供的功能外,我们还需要补充一些其他功能。最容易想到的情况就是权限过滤,我有一个类做某项业务,但是由于安全原因只有某些用户才可以调用这个类,此时我们就可以做一个该类的代理类,要求所有请求必须通过该代理类,由该代理类做权限判断,如果安全则调用实际类的业务开始处理。可能有人说为什么我要多加个代理类?我只需要在原来类的方法里面加上权限过滤不就完了吗?在程序设计中有一个类的单一性原则问题,这个原则很简单,就是每个类的功能尽可能单一。为什么要单一,因为只有功能单一这个类被改动的可能性才会最小,就拿刚才的例子来说,如果你将权限判断放在当前类里面,当前这个类就既要负责自己本身业务逻辑、又要负责权限判断,那么就有两个导致该类变化的原因,现在如果权限规则一旦变化,这个类就必需得改,显然这不是一个好的设计。
2、原理
为了保持行为的一致性,代理类和委托类通常会实现相同的接口,所以在访问者看来两者没有丝毫的区别。通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间,从而在设计上获得了更大的灵活性
3、代码示例
package com.itheima.spring.proxy;
public interface PersonDao {
public void savePerson();
}
package com.itheima.spring.proxy;
public class PersonDaoImpl implements PersonDao{
@Override
public void savePerson() {
System.out.println("save person");
}
}
package com.itheima.spring.proxy;
public class PersonDaoProxy implements PersonDao{
private PersonDao personDao;
private Transaction transaction;
public PersonDaoProxy(PersonDao personDao, Transaction transaction) {
super();
this.personDao = personDao;
this.transaction = transaction;
}
/**
* 1.开启事务
* 2.执行目标方法
* 3.事务提交
*/
@Override
public void savePerson() {
/*
* 可以在此加入权限判断验证的代码,不符合条件抛出异常
*/
this.transaction.beginTransaction();
this.personDao.savePerson();
this.transaction.commit();
}
}
package com.itheima.spring.proxy;
public class Transaction {
public void beginTransaction(){
System.out.println("begin transcation");
}
public void commit() {
System.out.println("commit");
}
}
package com.itheima.spring.proxy;
import org.junit.Test;
public class ProxyTest {
@Test
public void test() {
PersonDao personDao = new PersonDaoImpl();
Transaction transaction = new Transaction();
PersonDaoProxy proxy = new PersonDaoProxy(personDao,transaction);
proxy.savePerson();
}
}
begin transcation
save person
commit
在此会发现一个问题,在PersonDaoProxy这个类中,没有一个事务操作方法的方法,就要重新开启事务提交事务,一个代理只能为一个接口提供服务,等等问题,试想如果有多个操作方法,或者这个类实现了多个接口,会很麻烦。
其实最终要实现的目标是这样的:(beginTrasaction() 和 commit() 只用写一遍就好了)
静态代理的缺点:
静态代理的优点:
0 0
- 代理模式--动态代理
- 代理模式-静态代理
- 代理模式-静态代理
- 代理模式 & 动态代理
- 代理模式--静态代理
- 代理模式--动态代理
- 代理模式(动态代理)
- 代理模式-动态代理
- 代理模式-动态代理
- 代理模式动态代理
- 代理模式-静态代理
- 代理模式-动态代理
- 代理模式 -动态代理
- 代理模式---动态代理
- 代理模式-动态代理
- 代理模式--静态代理
- 代理模式!
- 代理模式
- Shaders for Game Programmers and Artists(6) - 反射与折射
- Spring容器启动过程
- node.js(express)连接mongoDB入门指导
- 多子目录的makefile编译库模板
- 贝叶斯推断及其互联网应用(一)
- 代理模式
- Java并发编程系列(二)----synchronized锁详解
- 安卓视频框架vitamio使用入门
- 贝叶斯推断及其互联网应用(二):过滤垃圾邮件
- 如何让孩子爱上设计模式 ——10.桥接模式(Bridge Pattern)
- Android手机病毒分析(二)
- AOP
- 贝叶斯推断及其互联网应用(三):拼写检查
- 学习图谱