OO模式-Proxy模式静态代理

     还依稀记得那个很经典的例子,王五喜欢一个女孩,但是过于害羞,让同伴李四代替自己去送花,最后女孩收到了话,但是猜想一下结果…………1、女孩很高兴,但是不知道到底是谁送的花;2、女孩很高兴李四送给自己花,并对李四有好感;3、女孩知道是王五托李四送给自己的话,心里甚是感激之情。当然咱们的重点并非是猜想最后的结果是什么,而是分析其实本来王五的事情却让李四去帮忙完成,没有直接和女孩交涉,这其实就是一个代理模式。

     我们用一个简单的小实例来描述一下,到底何为代理?为什么要用代理?

     先举一个小例子,比如我们只写一个简单的增删改查的小功能,需要创建两个类,一个接口类,一个实现类,然后最后是客户端调用,代码如下:

接口类:

		public interface UserManager {
			// 简单的增删改查方法
			public void addUser(String userId, String userName);
		
			public void delUser(String userId);
		
			public void modifyUser(String userId, String userName);
		
			public String findUser(String userId);
		}
实现类:

		public class UserManagerImpl implements UserManager {
		
			@Override
			public void addUser(String userId, String userName) {
				// 实现
				System.out.println("UserManagerImpl.addUser() userId ==>" + userId);
		
			}
		
			@Override
			public void delUser(String userId) {
				System.out.println("UserManagerImpl.delUser() userId ==>" + userId);
		
			}
		
			@Override
			public void modifyUser(String userId, String userName) {
				System.out.println("UserManagerImpl.modifyUser() userId ==>" + userId);
		
			}
		
			@Override
			public String findUser(String userId) {
				System.out.println("UserManagerImpl.findUser() userId ==>" + userId);
				return "huohuo";
			}
		
		}
最后客户端调用:

		public static void main(String[] args) {
				UserManager userManager = new UserManagerImpl();
		
				// 调用添加方法
				userManager.addUser("0001", "huohuo");
				// 调用查找方法
				userManager.findUser("0001");

}
最后的单元测试结果显示:

     到这里我们的小测试就完成了,但是看客户端方法,我们的用户直接调用了接口的实现类,这是万万不能的,如果我有大量的方式都来调用我们的实现类,这显然是不合理的,最好的情况还是避免直接交互的方式。现在不考虑这些,我们更换需求,要求在方法执行之前以及执行之后都进行提示,我们该如何去做?

     看我们的实现类,其实就是在前后加两句输出代码来表示一下:

					@Override
					public void addUser(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 (Exception e) {
							// TODO: handle exception
							e.printStackTrace();
							// 执行失败测试
							System.out.println("error ==>addUser()");
						}

     在实现中对每一个方法都增加同样的设置

     客户端依旧如此调用,最后的效果图也只是前后多了两条输出语句。

     代码执行完之后,我们思考一下,如果我有10个方法,我就得写10个同样的设置,最后终于写完了,但是老板突然又想改成别的需求了,比如只需要执行完提示就行,这样的话,就得一一的去每个方法中将不必要的提示去除掉……对于这种情况又该如何是好?所以我们这时候就可以考虑到我们的代理类模式

GoF定义代理模式:为其他对象提供一种代理以控制对这个对象的访问

     针对上边的小例子,我们可以直接创建一个代理类来控制客户端对实现类的直接访问,代理类和其目标对象是一样的,所以两者实现共同的接口

新增的代理类:

						/**
						 * 
						 * @ClassName: UserManagerImplProxy   
						 * @Description: 代理类,避免用户直接访问实现,和真实实体实现相同的接口
						 * @author: HuoYaJing  
						 * @date:2015年11月2日 下午8:46:10
						 */
						public class UserManagerImplProxy implements UserManager {
						
							private UserManager userManager;
						
							// 创造一个构造方法,来传送目标
							public UserManagerImplProxy(UserManager userManager) {
								this.userManager = userManager;
							}
						
							@Override
							public void addUser(String userId, String userName) {
						
								try {
									// 运行之前测试
									System.out.println("start ==>addUser() userId ==>" + userId);
									userManager.addUser(userId, userName);
									// 执行成功测试
									System.out.println("success ==>addUser()");
								} catch (Exception e) {
									// TODO: handle exception
									e.printStackTrace();
									// 执行失败测试
									System.out.println("error ==>addUser()");
								}
						
							}
     我们客户端调用的时候,则避免了和实现类的直接访问,通过调用代理类来实现。

publicstatic void main(String[] args) {

//                UserManageruserManager = new UserManagerImpl();

//                直接对代理类进行操作(代理类调用目标函数,目标函数调用实现类)

UserManageruserManager=new UserManagerImplProxy(new UserManagerImpl());

// 调用添加方法

userManager.addUser("0001","huohuo");

// 调用查找方法

userManager.findUser("0001");

}

     最后的结果肯定也是和之前的结果是一样的,执行成功显示成功,执行失败,显示error提示。

     这样通过代理类的出现,避免了用户直接访问目标函数,通过代理类的控制来进行访问。只是简单的加了一个代理类,这就是我们说的静态代理,静态代理存在什么问题呢?

  • 需要建立大量的代理类,比如我增加方法需要代理类,删除方法也需要代理类……
  • 重复的代码会出现在各个角落(和上一点是对应的)
     由于静态代理的缺陷,所以动态代理才诞生,详情下篇博客-《OO模式-Proxy模式<二>动态代理》

posted on 2015-11-03 11:24  huohuoL  阅读(130)  评论(0编辑  收藏  举报

导航