


Explication détaillée du code pour l'implémentation du mode proxy Java (Proxy)
Diagramme de classes
/** * 游戏者接口 * @author stone * */ public interface IGamePlayer { // 登录游戏 public void login(String user, String password); // 杀怪,网络游戏的主要特色 public void killBoss(); // 升级 public void upgrade(); }
/** * 游戏者 * @author stone * */ public class GamePlayer 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("登录名为" + user + " 的角色 " + this.name + "登录成功!"); } // 升级,升级有很多方法,花钱买是一种,做任务也是一种 public void upgrade() { System.out.println(this.name + " 又升了一级!"); } }
/** * 客户端 对被代理对象不可见 */ public class GamePlayerProxy implements IGamePlayer { private IGamePlayer gamePlayer = null;//被代理对象 // 通过构造函数传递要对谁进行代练 public GamePlayerProxy(String username) { this.gamePlayer = new GamePlayer(username); } // 代练杀怪 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 GamePlayerProxy2 implements IGamePlayer { private IGamePlayer gamePlayer = null;//被代理对象 // 通过构造函数传递要对谁进行代练 public GamePlayerProxy2(String username) { this.gamePlayer = new GamePlayer(username); } // 代练杀怪 public void killBoss() { this.gamePlayer.killBoss(); } // 代练登录 public void login(String user, String password) { System.out.println("登录时间是:" + new Date().toLocaleString()); this.gamePlayer.login(user, password); } // 代练升级 public void upgrade() { this.gamePlayer.upgrade(); System.out.println("升级时间是:" + new Date().toLocaleString()); } }
/* * 客户端 对被代理对象不可见 */ public class GamePlayerProxy3 { private IGamePlayer gamePlayer; // 通过构造函数传递 被代练(代理)对象 public GamePlayerProxy3(IGamePlayer gamePlayer) { this.gamePlayer = gamePlayer; System.out.println("我是一名代练,我玩的角色是别人的,可以动态传递进来"); } public IGamePlayer getProxy() { return (IGamePlayer) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{IGamePlayer.class}, new MyInvocationHandler()); } private class MyInvocationHandler implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getName().equals("login")) { System.out.println("登录时间是:" + new Date().toLocaleString()); } if (method.getName().equals("upgrade")) { System.out.println("升级时间是:" + new Date().toLocaleString()); } method.invoke(gamePlayer, args); return null; } } }
/* * 代理模式:为其他对象提供一种代理以控制对这个对象的访问。 * 在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用 * 优点 (1).职责清晰 真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。 (2).代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了的作用和保护了目标对象的作用。 (3).高扩展性 模式结构 一个是真正的你要访问的对象(目标类),一个是代理对象,真正对象与代理 对象实现同一个接口,先访问代理类再访问真正要访问的对象。 在装饰器模式和代理模式之间还是有很多差别的。装饰器模式关注于在一个对象上动态的添加方法,然而代理模式关注于控制对对象的访问。 换句话 说,用代理模式,代理类(proxy class)可以对它的客户隐藏一个对象的具体信息。因此,当使用代理模式的时候,我们常常在一个代理类中创建一个对象的实例。 并且,当我们使用装饰器模 式的时候,我们通常的做法是将原始对象作为一个参数传给装饰者的构造器。 我们可以用另外一句话来总结这些差别:使用代理模式,代理和真实对象之间的的关系通常在编译时就已经确定了,而装饰者能够在运行时递归地被构造。 */ public class Test { public static void main(String[] args) { /* * 普通的静态代理: 客户端不知道被代理对象,由代理对象完成其功能的调用 */ IGamePlayer proxy = new GamePlayerProxy("X"); System.out.println("开始时间是:" + new Date().toLocaleString()); proxy.login("zhangSan", "abcd"); proxy.killBoss(); proxy.upgrade(); System.out.println("结束时间是:" + new Date().toLocaleString()); System.out.println(); /* * 代理对象 增强了 被代理对象的功能 */ IGamePlayer proxy2 = new GamePlayerProxy2("M"); proxy2.login("lisi", "efg"); proxy2.killBoss(); proxy2.upgrade(); System.out.println(); /* * 动态代理:使用jdk提供的InvocationHandler,反射调用被代理对象的方法 * 结合java.reflect.Proxy 产生代理对象 * 动态传入被代理对象构造InvocationHandler,在handler中的invoke时可以增强被代理对象的方法的功能 * 或者说:(面向切面:)在什么地方(连接点), 执行什么行为(通知) * GamePlayerProxy3中是方法名为login时通知开始时间,upgrade时通知结束时间 */ GamePlayerProxy3 dynamic = new GamePlayerProxy3(new GamePlayer("Y")); IGamePlayer dynamicPlayer = dynamic.getProxy(); dynamicPlayer.login("wangwu", "1234"); dynamicPlayer.killBoss(); dynamicPlayer.upgrade(); /* * 面向切面: 一些相似的业务逻辑需要加在众多的地方,那们就可以把它提取到切面中, 切面也就是事务切面:如日志切面、权限切面、业务切面 */ } }
Impression :
开始时间是:2014-10-8 17:19:05 登录名为zhangSan 的角色 X登录成功! X 在打怪! X 又升了一级! 结束时间是:2014-10-8 17:19:05 登录时间是:2014-10-8 17:19:05 登录名为lisi 的角色 M登录成功! M 在打怪! M 又升了一级! 升级时间是:2014-10-8 17:19:05 我是一名代练,我玩的角色是别人的,可以动态传递进来 登录时间是:2014-10-8 17:19:05 登录名为wangwu 的角色 Y登录成功! Y 在打怪! 升级时间是:2014-10-8 17:19:05 Y 又升了一级!
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Guide de la racine carrée en Java. Nous discutons ici du fonctionnement de Square Root en Java avec un exemple et son implémentation de code respectivement.

Guide du nombre parfait en Java. Nous discutons ici de la définition, comment vérifier le nombre parfait en Java ?, des exemples d'implémentation de code.

Guide du numéro Armstrong en Java. Nous discutons ici d'une introduction au numéro d'Armstrong en Java ainsi que d'une partie du code.

Guide du générateur de nombres aléatoires en Java. Nous discutons ici des fonctions en Java avec des exemples et de deux générateurs différents avec d'autres exemples.

Guide de Weka en Java. Nous discutons ici de l'introduction, de la façon d'utiliser Weka Java, du type de plate-forme et des avantages avec des exemples.

Guide du nombre de Smith en Java. Nous discutons ici de la définition, comment vérifier le numéro Smith en Java ? exemple avec implémentation de code.

Dans cet article, nous avons conservé les questions d'entretien Java Spring les plus posées avec leurs réponses détaillées. Pour que vous puissiez réussir l'interview.

Java 8 présente l'API Stream, fournissant un moyen puissant et expressif de traiter les collections de données. Cependant, une question courante lors de l'utilisation du flux est: comment se casser ou revenir d'une opération FOREAK? Les boucles traditionnelles permettent une interruption ou un retour précoce, mais la méthode Foreach de Stream ne prend pas directement en charge cette méthode. Cet article expliquera les raisons et explorera des méthodes alternatives pour la mise en œuvre de terminaison prématurée dans les systèmes de traitement de flux. Lire plus approfondie: Améliorations de l'API Java Stream Comprendre le flux Forach La méthode foreach est une opération terminale qui effectue une opération sur chaque élément du flux. Son intention de conception est
