设计模式-代理模式

Provide a surrogate or placeholder for another object to control access to it.
	为其他对象提供一种代理以控制对这个对象的访问。
	
	public interface Subject {

		public void request();
	}
	
	public class Proxy implements Subject {

		private Subject subject = null;
		
		public Proxy() {
			this.subject = new Proxy();
		}
		
		public Proxy(Subject subject) {
			this.subject = subject;
		}
		
		public Proxy(Object ...objects) {
			
		}
		
		@Override
		public void request() {
			
			this.before();
			this.subject.request();
			this.after();
		}

		private void before() {
			
		}
		
		private void after() {
			
		}
	}
	
	代理模式的优点
	(1)职责清晰
	(2)高扩展性
	(3)智能化
	
	代理模式的扩展
	(1)普通代理
	public class GamePlayer implements IGamePlayer {

		private String name = "";
		
		public GamePlayer(IGamePlayer gamePlayer, String name) throws Exception {
			if (gamePlayer == null) {
				throw new Exception("can not create real role.");
			} else {
				this.name = name;
			}
		}
		
		@Override
		public void login(String user, String password) {
			System.out.println("login name: " + user + " passwod: " + password);
		}

		@Override
		public void killBoss() {
			System.out.println(this.name + " killBoss");
		}

		@Override
		public void upgrade() {
			System.out.println(this.name + " upgrade");
		}

	}
	
	public class GamePlayerProxy implements IGamePlayer {

		private IGamePlayer gamePlayer = null;
		
		public GamePlayerProxy(String name) {
			try {
				gamePlayer = new GamePlayer(this, name);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		@Override
		public void login(String user, String password) {
			System.out.println("login name: " + user + " passwod: " + password);
		}

		@Override
		public void killBoss() {
			this.gamePlayer.killBoss();
		}

		@Override
		public void upgrade() {
			this.gamePlayer.upgrade();
		}

	}
	
	在普通的代理模式下,调用者只知道代理而不用知道真实的角色是谁,屏蔽了真实角色的变更对高层模块的影响。
	真实的主题角色想怎么修改就怎么修改,对高层次的模块没有任何的影响,只要你实现了接口所对应的方法。
	
	(2)强制代理
	强制代理要求必须通过真实的角色找到代理角色,否则你不能访问。
	public interface IGamePlayer {
	
		public void login(String name, String password);
		
		public void killBoss();
		
		public void upgrade();
		
		public IGamePlayer getProxy();

	}
	
	public class GamePlayer implements IGamePlayer {

		private String name = "";
		private IGamePlayer proxy = null;
		
		public GamePlayer(String name) {
			this.name = name;
		}
		
		@Override
		public void login(String user, String password) {
			if (this.isProxy()) {
				System.out.println("login name: " + user + " passwod: " + password);
			} else {
				System.out.println("use the assigned proxy.");
			}
		}

		@Override
		public void killBoss() {
			if (this.isProxy()) {
				System.out.println(this.name + " killBoss");
			} else {
				System.out.println("use the assigned proxy.");
			}
		}

		@Override
		public void upgrade() {
			if (this.isProxy()) {
				System.out.println(this.name + " upgrade");
			} else {
				System.out.println("use the assigned proxy.");
			}
		}

		@Override
		public IGamePlayer getProxy() {
			this.proxy = new GamePlayerProxy(this);
			return this.proxy;
		}
		
		private boolean isProxy() {
			if (this.proxy == null) {
				return false;
			} else {
				return true;
			}
		}

	}
		
	public class GamePlayerProxy implements IGamePlayer {

		private IGamePlayer gamePlayer = null;
		
		public GamePlayerProxy(IGamePlayer gamePlayer) {
			this.gamePlayer = gamePlayer;
		}
		
		@Override
		public void login(String name, String password) {
			this.gamePlayer.login(name, password);
		}

		@Override
		public void killBoss() {
			this.gamePlayer.killBoss();
		}

		@Override
		public void upgrade() {
			this.gamePlayer.upgrade();
		}

		@Override
		public IGamePlayer getProxy() {
			return this;
		}

	}	
	
	public class Client {

		public static void main(String[] args) {
			
			IGamePlayer gamePlayer = new GamePlayer("zhangsan");
			IGamePlayer proxy = gamePlayer.getProxy();
			
			proxy.login("zhangsan", "2q3");
			proxy.killBoss();
			proxy.upgrade();
		}
	}
			
	(3)代理是有个性的
		一个类可以实现多个接口,完成不同任务的整合。也就是说代理类不仅可以实现主题接口,也可以实现其他
		接口,完成不同的任务,而且代理的目的是在目标对象方法的基础上作增强,这种增强的本质通常就是对目
		标对象的方法进行拦截和过滤。
		
	public interface IProxy {

		public void count();
	}
	
	public class GamePlayerProxy implements IGamePlayer, IProxy {

		private IGamePlayer gamePlayer = null;
		
		public GamePlayerProxy(IGamePlayer gamePlayer) {
			this.gamePlayer = gamePlayer;
		}
		
		@Override
		public void count() {
			System.out.println("upgrade cost 50 ruan.");
		}

		@Override
		public void login(String user, String password) {
			this.gamePlayer.login(user, password);
		}

		@Override
		public void killBoss() {
			this.gamePlayer.killBoss();
		}

		@Override
		public void upgrade() {
			this.gamePlayer.upgrade();
			this.count();
		}

	}
		
		代理类不仅仅是可以有自己的运算方法,通常的情况下代理的职责并不一定单一,它可以组合其他的
		真实角色,也可以实现自己的职责。代理类可以为真实角色预处理消息、过滤消息、转发消息、事后
		处理消息等。
		
		(4)动态代理
		一个类的动态代理是这样的一个类,由InvocationHandler 的实现类实现所有的方法,由其invoke方
		法接管所有方法的实现。动态代理的主要问题是解决我们通常说的“审计”问题,也就是横切面编程。
		在不改变我们已有的代码结构的情况下增强或控制对象的行为。
	public interface IGamePlayer {
	
		public void login(String user, String password);
		
		public void killBoss();
		
		public void upgrade();

	}
	
	public class GamePlayIH implements InvocationHandler {
	
		Class cls = null;
		Object obj = null;
		
		public GamePlayIH(Object object) {
			this.obj = object;
		}

		@Override
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			
			Object result = method.invoke(this.obj, args);
			if (method.getName().equalsIgnoreCase("login")) {
				System.out.println("my id has been used...");
			}
			return result;
		}

	}
	
	public class GamePlayer implements IGamePlayer {

		private String name;
		
		public GamePlayer(String name) {
			this.name = name;
		}
		
		@Override
		public void login(String user, String password) {
			System.out.println("login name: " + user + " passwod: " + password);
		}

		@Override
		public void killBoss() {
			System.out.println(this.name + " killBoss");
		}

		@Override
		public void upgrade() {
			System.out.println(this.name + " upgrade");
		}

	}
			
	public class Client {

		public static void main(String[] args) {
			
			IGamePlayer player = new GamePlayer("zhangsan");
			InvocationHandler handler = new GamePlayIH(player);
			
			ClassLoader cl = player.getClass().getClassLoader();
			// 动态产生一个代理者
			IGamePlayer proxy = (IGamePlayer) Proxy.newProxyInstance(cl, new Class[]{IGamePlayer.class}, handler);
			
			proxy.login("zhangsan", "2233");
			proxy.killBoss();
			proxy.upgrade();
			
		}

	}

你可能感兴趣的:(设计模式)