Maison  >  Article  >  Java  >  Notes sur le modèle d'agent des modèles de conception Java

Notes sur le modèle d'agent des modèles de conception Java

黄舟
黄舟original
2017-10-18 09:39:001118parcourir

Cet article présente principalement en détail les notes du mode proxy du modèle de conception Java, qui ont une certaine valeur de référence. Les amis intéressés peuvent se référer au

Mode proxy :

Le modèle proxy est un modèle structurel pour les objets. Le modèle de proxy fournit un objet proxy pour un objet, et l'objet proxy contrôle la référence à l'objet d'origine.

Fonction principale :

Contrôler l'accès aux objets via des proxys.


Vous pouvez contrôler en détail la méthode d'accès à un certain objet (d'un certain type), effectuer un pré-traitement avant d'appeler cette méthode et effectuer un post-traitement après avoir appelé cette méthode. C'est-à-dire la micro-implémentation d'AOP.


Le mécanisme de mise en œuvre de base de l'AOP (Aspect Oriented Programming).


Scènes de la vie :

Ce qu'on appelle l'agence, c'est lorsqu'une personne ou une institution agit au nom d'une autre personne ou institution. Dans certains cas, un client ne veut pas ou ne peut pas référencer directement un objet, et un objet proxy peut servir d'intermédiaire entre le client et l'objet cible.

Par exemple, si un client veut trouver une star pour chanter, il doit d'abord trouver son agent, puis son agent fera en sorte que la star chante.
L'agent doit gérer certains pré-traitements avant le concert (interviews, rédaction du contrat, signature, encaissement de l'acompte, organisation des billets d'avion et des véhicules, etc.) et doit gérer certains post-traitements (clôture du paiement, etc. ) après le concert. À l'heure actuelle, une certaine star (un vrai personnage) n'a qu'à se soucier de la façon de chanter, et toutes les autres questions sont laissées au manager (agent).

Rôle principal :

Écrivez la description de l'image ici

Rôle d'objet abstrait : déclare l'interface commune entre les objets proxy et les objets réels, définit les objets proxy et Méthodes externes publiques d'objets réels. Cela permet à l'objet proxy d'être utilisé partout où un objet réel peut être utilisé.

Rôle de l'objet réel : définit l'objet réel représenté par l'objet proxy. Implémentez des objets abstraits et définissez la logique métier qui doit être implémentée par des objets réels pour les appels par des objets proxy. Concentrez-vous sur la véritable logique métier.

Rôle d'objet proxy : implémente des objets abstraits et est un proxy pour les objets réels. Il implémente des méthodes abstraites via les méthodes de logique métier des objets réels et attache ses propres opérations. Mettez le contrôle de processus unifié dans les objets proxy.


L'objet proxy contient une référence à l'objet réel en interne, de sorte que l'objet réel puisse être utilisé à tout moment ; l'objet proxy fournit la même interface que l'objet réel, de sorte que l'objet réel peut être remplacé à tout moment. L'objet proxy effectue généralement une opération avant ou après que l'appel client soit transmis à l'objet réel, plutôt que de simplement transmettre l'appel à l'objet réel.

Scénarios d'application :

Procuration de sécurité : Bloquez l'accès direct aux personnages réels.

Proxy à distance : gérez les appels de méthodes à distance via des classes proxy.
Chargement paresseux : chargez d'abord des objets proxy légers, puis chargez des objets réels si nécessaire. (Chargement paresseux des images)

Catégorie :

Procuration statique : (classe proxy définie statiquement)

Code pour l'exemple ci-dessus :

1. Déclare l'interface commune entre l'objet proxy et l'objet réel, et définit les méthodes externes publiques de l'objet proxy et de l'objet réel.


public interface Star {
  /**
   * 面谈
   */
  void confer();
  /**
   * 签合同
   */
  void signContract();
  /**
   * 订票
   */
  void bookTicket();
  /**
   * 唱歌
   */
  void sing();
  /**
   * 收钱
   */
  void collectMoney();
}
2. Définissez une classe d'objets réelle et implémentez les méthodes fournies par l'interface abstraite.


public class RealStar implements Star {

  @Override
  public void bookTicket() {
    System.out.println("RealStar.bookTicket()");
  }

  @Override
  public void collectMoney() {
    System.out.println("RealStar.collectMoney()");
  }

  @Override
  public void confer() {
    System.out.println("RealStar.confer()");
  }

  @Override
  public void signContract() {
    System.out.println("RealStar.signContract()");
  }

  @Override
  public void sing() {
    System.out.println("RealStar.sing()");
  }
}
3. Définissez une classe d'objet proxy, implémentez les méthodes fournies par l'interface abstraite et conservez une référence à l'objet réel.


public class ProxyStar implements Star{

private Star star;

  public ProxyStar(Star star) {
    super();
    this.star = star;
  }

  @Override
  public void bookTicket() {
    System.out.println("ProxyStar.bookTicket()");
  }

  @Override
  public void collectMoney() {
    System.out.println("ProxyStar.collectMoney()");
  }

  @Override
  public void confer() {
    System.out.println("ProxyStar.confer()");
  }

  @Override
  public void signContract() {
    System.out.println("ProxyStar.signContract()");
  }

  @Override
  public void sing() {
    star.sing();
  }

}
4. Classe de test


public class Client {
  public static void main(String[] args) {
    //定义真实对象角色
    Star realStar = new RealStar();
    //定义代理对象角色,内部含有真实对象的引用
    Star proxyStar = new ProxyStar(realStar);

    proxyStar.confer();
    proxyStar.signContract();
    proxyStar.bookTicket();
    proxyStar.sing();
    proxyStar.collectMoney();

  }
}
Les résultats en cours d'exécution sont les suivants :


ProxyStar.confer()
ProxyStar.signContract()
ProxyStar.bookTicket()
RealStar.sing()
ProxyStar.collectMoney()
À partir de l'exemple ci-dessus, nous pouvons voir que l'objet proxy délègue l'appel du client à l'objet réel, et peut effectuer des opérations spécifiques avant et après l'appel de la méthode de la cible objet.


Proxy dynamique : (classe proxy générée dynamiquement) :

Avantages du proxy dynamique par rapport au proxy statique :

En rôle abstrait Tous les méthodes déclarées (interface) sont transférées vers une méthode centralisée d'appel du serveur pour traitement, afin que nous puissions gérer de nombreuses méthodes de manière plus flexible et uniforme.


Proxy dynamique fourni avec JDK

java.lang.reflect.Proxy
Générer dynamiquement des classes et des objets proxy

java.lang.reflect.InvocationHandler (interface processeur)
L'accès proxy aux rôles réels peut être obtenu via la méthode d'invocation

Générer une classe proxy via Proxy chacun time L'objet doit spécifier l'objet processeur correspondant

Le code de test est le suivant :

1 Déclarez l'interface commune de l'objet proxy et de l'objet réel, et définissez les méthodes externes publiques du. objet proxy et l'objet réel.


public interface Star {
  /**
   * 面谈
   */
  void confer();
  /**
   * 签合同
   */
  void signContract();
  /**
   * 订票
   */
  void bookTicket();
  /**
   * 唱歌
   */
  void sing();
  /**
   * 收钱
   */
  void collectMoney();
}
2. Définissez une classe d'objets réelle et implémentez les méthodes fournies par l'interface abstraite.


public class RealStar implements Star {

  @Override
  public void bookTicket() {
    System.out.println("RealStar.bookTicket()");
  }

  @Override
  public void collectMoney() {
    System.out.println("RealStar.collectMoney()");
  }

  @Override
  public void confer() {
    System.out.println("RealStar.confer()");
  }

  @Override
  public void signContract() {
    System.out.println("RealStar.signContract()");
  }

  @Override
  public void sing() {
    System.out.println("RealStar.sing()");
  }
}
3. Définissez une classe StarHandler pour implémenter l'interface du processeur InvocationHandler. Vous pouvez obtenir un accès proxy aux rôles réels via la méthode d'invocation, et vous pouvez également utiliser la méthode d'invocation. méthode d'invocation pour accéder à plusieurs Les opérations sont gérées de manière uniforme.


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class StarHandler implements InvocationHandler{

  private Star realStar;

  public StarHandler(Star realStar) {
    super();
    this.realStar = realStar;
  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args)
      throws Throwable {
    //返回值
    Object object = null;

    System.out.println("真正的方法执行前!");
    System.out.println("面谈,签合同,预付款,订机票");

    if(method.getName().equals("sing")){
      object = method.invoke(realStar, args);
    }

    System.out.println("真正的方法执行后!");
    System.out.println("收尾款");
    return object;

  }

}

4.客户端测试类


import java.lang.reflect.Proxy;

public class Client {

public static void main(String[] args) {

    Star realStar = new RealStar();
    StarHandler handler = new StarHandler(realStar);

    //通过Proxy生成代理类对象并指定对应的处理器对象
    Star proxyStar = (Star)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), 
        new Class[]{Star.class}, handler);

    proxyStar.sing();

  }

运行结果如下:

真正的方法执行前!
面谈,签合同,预付款,订机票
RealStar.sing()
真正的方法执行后!
收尾款

开发框架中的应用场景

代理模式在开发框架中的应用场景是非常多的,实际上随便选择一个开发框架都有用到代理模式。例如:

mybatis中实现拦截器插件
AspectJ的实现
spring中AOP的实现

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn