代理模式复习
代理模式:为对象提供一种代理以控制对这个对象的访问。
应用场景:
1、 虚拟代理:我们很常见的就是在网速不好的时候访问类似淘宝这样图片比较多的网站,会先在相应的位置上显示图片框,然后一张一张的加载显示。
2、 安全代理:通过代理类控制对真实类的访问。
3、 智能代理:调用真实类时代理类处理一些其他的事务。
4、 。。。
个人感觉设计模式的应用场景很多,有大有小,只要是能够让我们更好的符合OCP原则都可以适当的使用。在DRP中静态代理的例子类似是智能代理的一种应用。
静态代理应用实例
在DRP项目中的应用场景为:用户要求添加打印日志的功能,有可能一段时间之后就不需要该功能或是要扩展其他的功能,这可以通过代理模式来实现
最原始的代码:
接口————
<span style="font-size:18px;">public interface UserManager {
public voidaddUser(String userId, String userName);
public void delUser(StringuserId);
}</span>
实现————
<span style="font-size:18px;">public class UserManagerImpl implements UserManager {
public voidaddUser(String userId, String userName) {
System.out.println("UserManagerImpl.addUser()userId-->>" + userId);
}
public voiddelUser(String userId) {
System.out.println("UserManagerImpl.delUser()userId-->>" + userId);
}
}</span>
客户端————
<span style="font-size:18px;">public class Client {
public static void main(String[] args) {
UserManageruserManager = new UserManagerImpl();//此处可配置
userManager.addUser("0001","张三");
}
}</span>
未使用代理前:
为了满足上述的需求,最简单原始的方法是从项目中找到UserManagerImplements类然后对其中的方法进行修改,添加打印代码如下:
实现————
<span style="font-size:18px;">public class UserManagerImpl implements UserManager {
public voidaddUser(String userId, String userName) {
//调用前
System.out.println("start-->>addUser()userId-->>" + userId);
try {
System.out.println("UserManagerImpl.addUser()userId-->>" + userId);
//调用成功
System.out.println("success-->>addUser()");
}catch(Exceptione) {
e.printStackTrace();
//调用失败
System.out.println("error-->>addUser()");
thrownew RuntimeException();
}
}
//del方法如上
public voiddelUser(String userId) {
System.out.println("UserManagerImpl.delUser()userId-->>" + userId);
}
}</span>
存在的问题:如果客户要求不再打印还是需要修改类,只有违背面向对象的“开闭原则”。
使用静态代理:
代理类————
public class UserManagerImplProxy implements UserManager {
privateUserManager userManager;
publicUserManagerImplProxy(UserManager userManager) {
this.userManager= userManager;
}
publicvoid addUser(String userId, String userName) {
try{
System.out.println("start-->>addUser()userId-->>" + userId);
userManager.addUser(userId,userName);
System.out.println("success-->>addUser()");
}catch(Exceptione) {
e.printStackTrace();
System.out.println("error-->>addUser()");
}
}
publicvoid delUser(String userId) {
}
}
客户端————
<span style="font-size:18px;">public class Client {
public static voidmain(String[] args) {
UserManager userManager= new UserManagerImplProxy(new UserManagerImpl());
userManager.addUser("0001","张三");
}
}</span>
这里客户端的代码做了修改,客户端应该是面向接口的这里我们可以把对类的实例化做成配置文件加工厂实现让客户端真正的面向接口,如果还有新的扩展功能可以增加其他的代理类,在配置文件中进行配置。
小结:
本次通过这个实例来学习代理模式对代理模式的认识又深了一步,原先理解的不透彻看大话上的例子只记得那个故事。代理模式是结构型,类型注定了代理模式是通过类的增减满足应用的需求。静态代理能够解决问题但是它的使用也存在一定的问题代码冗余、代理类数量在后期的扩展中可能较多不方便管理,下篇博客通过动态代理进一步的简化。