外贸代理合作模式 (设计模式代理)

栗子

定义一个游戏者接口

public interface IGamePlayer{
 // 登录游戏
 public void login(String user, String password);
 // 杀怪
 public void killBoss();
 // 升级
 public void upgrade();
}

定义游戏着类,实现游戏者接口

public class GamePlay implements IGamePlayer{
 private String name = "";
 // 构造函数注入
 public GamePlayer(String _name){
 this.name = _name;
 }
 // 打怪
 public void killBoss(){
 System.out.println(this.name + "在打怪");
 }
 // 登录
 public void login(String user, String password){
 System.out.println("登录");
 }
 // 升级
 public void upgrade(){
 System.out.println(this.name + "升级");
 }
}

场景类

public class Client{
 public static void main(String[] args){
 // 定义一个玩家
 IGamePlayer player = new GamePlayer("张三");
 // 开始游戏
 System.out.println("开始游戏");
 // 登录
 player.login("zangshan", "password");
 // 杀怪
 player.killBoss();
 // 升级
 player.upgrade();
 // 记录结束时间
 }
}

改进

增加一个代练

public class GamePlayerProxy implements IGamePlayer{}
 private IGamePlayer gamePlayer = null;
 // 构造函数注入
 public GamePlayerProxy(IGamePlayer _gamePlayer){
 this.gamePlayer = _gamePlayer;
 }
 // 代练
 public void killBoss(){
 this.gamePlayer.killBoss();
 }
 // 代练登录
 public void login(String user, String password){
 this.gamePlayer.login(user, password);
 }
 // 代练升级
 public void upgrade(){
 this.gamePlayer.upgrade();
 }
}

场景类如下

public class Client {
 public static void main(String[] args){
 // 定义一个玩家
 IGamePlayer player = new GamePlayer("张三");
 // 定义代练者
 IGamePlayer proxy = new GamePlayerProxy(player);
 // 开始游戏
 proxy.login("zangshan", "password");
 proxy.killBoss();
 // 升级
 proxy.upgrade();
 }
}

扩展

代理分为普通代理和透明代理

普通代理

普通代理要求客户端只能访问代理角色,不能访问真实角色。

// 普通代理的游戏者
public class GamePlayer implemnts IGamePlayer{
 private String name = "";
 // 构造函数传递姓名
 public GamePlayer(IGamePlayer _gamePlayer, String _name)throws Exception{
 if(_gamePlayer == null){
 throw new Exception("不能创建真实角色");
 }else{
 this.name = _name;
 }
 }
 // 打怪
 public void killBoss(){
 System.out.println(this.name + "在打怪!");
 }
 // 登录
 public void login(String user. String password){
 
 }
 // 升级
 public void upgrade(){
 
 }
 
}
// 普通代理的代理者
public class GamePlayerProxy implements IGamePlayer{
 private IGamePlayer gamePlayer = null;
 // 构造函数注入 
 public GamePlayerProxy(String name){
 try{
 gamePlayer = new GamePlayer(this, name);
 }catch(Exception e){
 
 }
 }
 // 代练
 public void killBoss(){
 this.gamePlayer.killBoss();
 }
 // 登录
 public void login(String user, String password){
 this.gamePlayer.login(user, password);
 }
 // 升级
 public void upgrade(){
 this.gamePlayer.upgrade();
 }
}

最后场景类

public class Client{
 public static void main(String[] args){
 // 定义代练者
 IGamePlayer proxy = new GamePlayerProxy("");
 // 开始
 proxy.login("", "password");
 // 升级
 proxy.upgrade();
 // 记录结束时间
 }
}

强制代理

public interface IGamePlayer{
 // 登录
 public void login(String user, 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;
 }
 // 找到代理
 public IGamePlayer getProxy(){
 this.proxy = new GamePlayerProxy(this);
 return this.proxy;
 }
 // 打怪
 public void killBoss(){
 if(this.isProxy()){
 
 }else{
 
 }
 }
 // 登录
 public void login(String user, String password){
 if(this.isProxy()){
 
 }else{
 
 }
 }
 // 升级
 public void upgrade(){
 if(this.isProxy()){
 
 }else{
 
 }
 }
 // 是否代理
 private boolean isProxy(){
 if(this.proxy == null){
 return false;
 }else{
 return true;
 }
 }
 
}
// 强制代理代理类
public class GamePlayerProxy implements IGamePlayer{
 private IGamePlayer gamePlayer = null;
 // 构造函数传递用户名
 public GamePlayerProxy(IGamePlayer _gaemPlayer){
 this.gamePlayer = _gamePlayer;
 }
 // 代练
 public void killBoss(){
 this.gaemPlayer.killBoss();
 }
 // 登录
 public void login(String user, String password){
 this.gamePlayer.login(user, password);
 }
 // 升级
 public void upgrade(){
 this.gamePlayer.upgrade();
 }
 // 如果代理没有,为自身
 public IGamePlayer getProxy(){
 return this;
 }
}

最后书写场景类

public class Client{
 public static void main(String[] args){
 // 定义游戏角色
 IGamePlayer player = new GamePlayer("张三");
 // 开始游戏
 player.login("zangshan", "password");
 // 杀怪
 player.killBoss();
 // 升级
 player.upgrade();
 }
}

强制代理场景类

public class Client{
 public static void main(String[] args){
 // 定义游戏角色
 IGamePlayer player = new GamePlayer("张三");
 // 获得指定代理
 IGamePlayer proxy = player.getProxy();
 // 开始打游戏
 proxy.login("zangshan", "password");
 // 开始杀怪
 proxy.killBoss();
 // 升级
 proxy.upgrade();
 }
}

代理需要拥有个性

即一个类可以实现多个接口,完成不同任务的整合。

// 定义代理类的接口
public interface IProxy{
 // 计算费用
 public void count();
}
// 定义代理类
public class GamePlayerProxy implements IGamePlayer, IProxy{
 private IGamePlayer gamePlayer = null;
 // 通过构造函数传递对谁代练
 public GamePlayerProxy(IGamePlayer _gamePlayer){
 this.gamePlayer = _gamePlayer;
 }
 // 代练
 public voidkillBoss(){
 this.gamePlayer.killBoss();
 }
 // 代练登录
 public void login(String user, String password){
 this.gamePlayer.login(user, password);
 }
 // 代练升级
 public void upgrade(){
 this.gamePlayer.upgrade();
 this.count();
 }
 // 计算费用
 public void count(){
 
 }
}

在上方中先实现了IProxy接口,然后再调用该接口中的方法,完成结算.

动态代理

动态代理在实现阶段不用关系代理谁。在运行阶段指定代理那个对象。

即,在实现的时候不用关心代理谁,只需要在运行的时候指定代理那个对象

// 动态代理类
public class GamePlayIH implements invocationHandler{
 // 被代理着
 Class cls = null;
 // 被代理的实例
 Object obj = null;
 // 我要代理谁
 public GamePlayerIH(Object _obj){
 this.obj = _obj;
 }
 // 调用被代理的方法
 public Object invoke(Object proxy, Method method, Object[] args)throws Throwable{
 Object result = method.invoke(this.obj, args);
 return result;
 }
}
// 动态代理场景类
public class Client{
 public static void main(String[] args)throws Throwable{
 // 定义一个痴迷的玩家
 IGamePlayer player = new GamePlayer("张三");
 // 定义一个handler
 invocationHandler handler = new GamePlayIH(player);
 // 开始游戏,记录时间戳
 System.out.println("开始时间");
 // 获得类的父类加载器
 ClassLoader cl = player.getClass().getClassLoader();
 // 动态产生代理者
 IGamePlayer proxy = (IGamePlayer)proxy.newProxyinstance(cl, new Class[]{IGamePlayer.class}, handler);
 // 登录
 proxy.login("zhangsan", "password");
 // 开始
 proxy.killBoss();
 // 升级
 proxy.upgrade();
 // 记录结束时间
 }
}

ps 动态代理直接在需要代理的时候直接动态生成代理

此时,如果需要登录的时候发送消息,此时修改如下

public class GamePlayIH implements invocationHandler {
 // 被代理着
 Class cls = null;
 // 被代理的实例
 Object obj = null;
 // 我要代理谁
 public GamePlayIH(Object _obj){
 this.obj = _obj;
 }
 // 调用代理的方法
 public Object invoke(Object proxy, Method method, Object[] args){
 Objetc result = method.invoke(this.obj, args);
 // 如股票是登录方法,发送消息
 if(method.getName().equalslgnoreCase("login")){
 
 }
 return result;
 }
}

这样就完成的消息的发送

最后

// 抽象主题
public interface Subject{
 // 业务操作
 public void doSomething(String str);
}
// 真实主题
public class RealSubject implements Subject{
 // 业务操作
 public void doSomething(String str){
 /// 业务操作
 }
}

下面是动态代理类该动态代理类通过构造函数将将对象传入。

由于实现了invoke方法,此时会被调度到该方法

public class MyinvocationHandler implements invocationHandler{
 // 被代理的对象
 private Object target = null;
 // 构造函数传递
 public MyInvocationHandler(Object _obj){
 this.target = _obj;
 }
 // 代理方法
 public Object invoke(Object proxy, Method method, Object[] args)throws Throwable{
 // 执行被代理的方法
 return method.invoke(this.target, args);
 }
}

下面是动态代理类

public class DynamiProxy{
 public static T newProxyinstance(ClassLoader loader, Class<?>[] interfaces, invocationHandler h){
 // 寻找JoinPoint连接点 
 // 寻找连接点,即方法执行前后的连接点
 if(true){
 // 执行一个前置通知
 new BeforeAdvice()*ex.e**c();
 }
 // 执行切面
 // 并返回结果
 return (T)Proxy.newProxyinstance(loader.interfaces, h);
 }
}

下面实现通知

public interface IAdvice{
 public void exec();
}
public class BeforeAdvice implements IAdvice{
 public void exec(){
 System.out.println("我是通知");
 }
}

最后书写场景类

public class Client{
 public static void main(String[] args){
 // 定义一个主题
 Subject subject = new RealSUbject();
 // 定义一个前置通知
 invocationHandler handler = new MyinvocationHandler(subject);
 // 定义主题代理
 Subject proxy = DynamicProxy.newProxyinstance(subject.getClass().getClassLoader(), subject.getClass().getinterfaces(),handler);
 // 最后执行这个代理的接口
 proxy.doSomething("Finish");
 }
}

总结 程序的执行的过程,在DynamicProxy类中,使用newProxyinstance方法重写生成一个对象,这个对象是其代理对象,一个类的动态代理是这样的过程

先场景类需要调用doSomething方法的时候,进入动态代理类,当动态代理类调用Proxy.newProxyinstance的时候,会调度到代理方法,由代理方法再执行method.invoke(this.target, args);完成对代理的调用。

https://www.iming.info/dai-li-mo-shi/