Comprendre et utiliser les Design Patterns peut cultiver nos bonnes habitudes de programmation orientée objet. En même temps, dans les applications pratiques, nous pouvons être aussi à l'aise qu'un poisson dans l'eau et profiter du plaisir de la facilité.
Le proxy est un mode plus utile, et il existe de nombreuses variantes. Les scénarios d'application couvrent les petites structures jusqu'aux grandes structures de l'ensemble du système. Nous pouvons avoir des concepts tels que les serveurs proxy. L'explication est la suivante : il existe une couche intermédiaire entre le point de départ et la destination, ce qui signifie agence.
Modèle de conception défini : fournissez un proxy pour d'autres objets afin de contrôler l'accès à cet objet.
Pourquoi utiliser le mode proxy
1. Mécanisme d'autorisation Les utilisateurs de différents niveaux ont des droits d'accès différents au même objet. Par exemple, dans le système de forum Jive, le proxy est utilisé pour contrôler le mécanisme d'autorisation. et accéder au forum. Il existe deux types de personnes : les utilisateurs enregistrés et les visiteurs (utilisateurs non enregistrés). Jive utilise des agents comme ForumProxy pour contrôler les droits d'accès de ces deux utilisateurs au forum.
2. Un client ne peut pas exploiter directement un objet, mais il doit interagir avec cet objet.
Deux situations spécifiques sont données à titre d'exemples :
1. Si l'objet est une très grande image et met beaucoup de temps à s'afficher, alors lorsque l'image est incluse dans le document, utilisez un éditeur ou un navigateur pour ouvrir ce document. Le document doit être ouvert très rapidement et vous ne pouvez pas attendre que la grande image soit traitée. Dans ce cas, vous devez créer une image proxy pour remplacer l'image réelle.
2. Si l'objet se trouve sur un serveur distant sur Internet, l'exploitation directe de l'objet peut être lente en raison de la vitesse du réseau, nous pouvons alors utiliser Proxy pour remplacer l'objet en premier.
En bref, le principe est que les objets coûteux ne doivent être créés que lorsqu'ils sont utilisés. Ce principe peut nous faire économiser beaucoup de mémoire Java précieuse. Par conséquent, certaines personnes pensent que Java consomme des ressources et de la mémoire. Je pense que cela a un certain lien avec les idées de programmation.
Comment utiliser le mode proxy
Prenons l'exemple du système de forum Jive. Il existe de nombreux types d'utilisateurs qui accèdent au système de forum : utilisateurs ordinaires enregistrés, gestionnaires de forum, gestionnaires de système et visiteurs. . Seuls les utilisateurs ordinaires enregistrés peuvent parler. Les gestionnaires de forum peuvent gérer les forums pour lesquels ils sont autorisés. Les gestionnaires de système peuvent gérer toutes les affaires, etc. Ces divisions d'autorité et cette gestion sont réalisées à l'aide d'un proxy.
Le Forum est l'interface principale de Jive. Les principaux comportements liés aux opérations du forum sont affichés dans le Forum, tels que le nom du forum, l'obtention et la modification de la description du forum, la publication, la suppression et la modification des messages, etc.
Les utilisateurs avec différents niveaux d'autorisations sont définis dans ForumPermissions :
public class ForumPermissions implements Cacheable { /** * Permission to read object. */ public static final int READ = 0; /** * Permission to administer the entire sytem. */ public static final int SYSTEM_ADMIN = 1; /** * Permission to administer a particular forum. */ public static final int FORUM_ADMIN = 2; /** * Permission to administer a particular user. */ public static final int USER_ADMIN = 3; /** * Permission to administer a particular group. */ public static final int GROUP_ADMIN = 4; /** * Permission to moderate threads. */ public static final int MODERATE_THREADS = 5; /** * Permission to create a new thread. */ public static final int CREATE_THREAD = 6; /** * Permission to create a new message. */ public static final int CREATE_MESSAGE = 7; /** * Permission to moderate messages. */ public static final int MODERATE_MESSAGES = 8; ..... public boolean isSystemOrForumAdmin() { return (values[FORUM_ADMIN] || values[SYSTEM_ADMIN]); } ..... }
Par conséquent, les différentes autorisations d'opération dans Forum sont liées aux niveaux d'utilisateurs définis par ForumPermissions, comme l'interface Implémentation du Forum : ForumProxy relie cette correspondance. Par exemple, pour modifier le nom du Forum, seul l'administrateur du forum ou l'administrateur système peut le modifier. Le code est le suivant :
public class ForumProxy implements Forum { private ForumPermissions permissions; private Forum forum; this.authorization = authorization; public ForumProxy(Forum forum, Authorization authorization, ForumPermissions permissions){ this.forum = forum; this.authorization = authorization; this.permissions = permissions; } ..... public void setName(String name) throws UnauthorizedException, ForumAlreadyExistsException{ //只有是系统或论坛管理者才可以修改名称 if (permissions.isSystemOrForumAdmin()) { forum.setName(name); } else { throw new UnauthorizedException(); } } ... }
Et DbForum est la véritable implémentation de l'interface Forum. le nom du forum à titre d'exemple :
public class DbForum implements Forum, Cacheable { ... public void setName(String name) throws ForumAlreadyExistsException { .... this.name = name; //这里真正将新名称保存到数据库中 saveToDb(); .... } ... }
Quand il s'agit de changer le nom du forum, les autres programmes doivent d'abord s'occuper de ForumProxy. ForumProxy décide s'il a le pouvoir de faire une certaine chose. une véritable « passerelle » et « système proxy de sécurité ».
Dans les applications quotidiennes, il est inévitable que l'autorisation du système ou le système de sécurité soit toujours impliqué. Que vous utilisiez Proxy consciemment ou non, vous utilisez déjà Proxy.
Continuons à parler en profondeur avec Jive. Ce qui suit concernera le mode usine.
Nous savons déjà que l'utilisation de Forum nécessite ForumProxy. La création d'un forum dans Jive utilise le mode Factory. Il existe une classe abstraite générale ForumFactory. Dans cette classe abstraite, l'appel de ForumFactory est implémenté via la méthode getInstance() Singleton. utilisé ici (également l'un des modèles de conception), et getInstance() renvoie ForumFactoryProxy.
Pourquoi ne pas renvoyer ForumFactory, mais renvoyer l'implémentation de ForumFactory, ForumFactoryProxy ? La raison est évidente. Vous devez utiliser un proxy pour déterminer si vous êtes autorisé à créer un forum.
Dans ForumFactoryProxy, nous voyons le code suivant :
public class ForumFactoryProxy extends ForumFactory { protected ForumFactory factory; protected Authorization authorization; protected ForumPermissions permissions; public ForumFactoryProxy(Authorization authorization, ForumFactory factory,ForumPermissions permissions){ this.factory = factory; this.authorization = authorization; this.permissions = permissions; } public Forum createForum(String name, String description) throws UnauthorizedException, ForumAlreadyExistsException{ //只有系统管理者才可以创建forum if (permissions.get(ForumPermissions.SYSTEM_ADMIN)) { Forum newForum = factory.createForum(name, description); return new ForumProxy(newForum, authorization, permissions); } else { throw new UnauthorizedException(); } } }
La méthode createForum renvoie également ForumProxy, comme un mur. Les autres programmes ne peuvent interagir qu'avec Proxy.
Remarquez qu'il y a deux proxys ici : ForumProxy et ForumFactoryProxy. Représente deux responsabilités différentes : utiliser le Forum et créer le Forum. Quant à savoir pourquoi l'utilisation d'objets et la création d'objets sont séparées, c'est aussi la raison pour laquelle le modèle Factory est utilisé : pour « encapsuler » et « répartir ». En d’autres termes, les fonctions doivent être aussi simples que possible pour faciliter la maintenance et la modification.
La création et l'utilisation d'autres messages dans le système de forum Jive sont toutes basées sur l'idée du Forum.
Ci-dessus, nous avons expliqué comment utiliser le proxy pour accéder au mécanisme d'autorisation. Le proxy peut également masquer aux utilisateurs une autre méthode d'optimisation appelée copie sur écriture. La copie d'un objet volumineux et complexe est une opération coûteuse si l'objet d'origine n'est pas modifié pendant le processus de copie, une telle surcharge de copie est alors inutile. Utilisez un proxy pour retarder ce processus de copie.
比如:我们有一个很大的Collection,具体如hashtable,有很多客户端会并发同时访问它。其中一个特别的客户端要进行连续的数据获取,此时要求其他客户端不能再向hashtable中增加或删除 东东。
最直接的解决方案是:使用collection的lock,让这特别的客户端获得这个lock,进行连续的数据获取,然后再释放lock。
public void foFetches(Hashtable ht){ synchronized(ht){ //具体的连续数据获取动作.. } }
但是这一办法可能锁住Collection会很长时间,这段时间,其他客户端就不能访问该Collection了。
第二个解决方案是clone这个Collection,然后让连续的数据获取针对clone出来的那个Collection操作。这个方案前提是,这个Collection是可clone的,而且必须有提供深度clone的方法。Hashtable就提供了对自己的clone方法,但不是Key和value对象的clone。
public void foFetches(Hashtable ht){ Hashttable newht=(Hashtable)ht.clone(); }
问题又来了,由于是针对clone出来的对象操作,如果原来的母体被其他客户端操作修改了,那么对clone出来的对象操作就没有意义了。
最后解决方案:我们可以等其他客户端修改完成后再进行clone,也就是说,这个特别的客户端先通过调用一个叫clone的方法来进行一系列数据获取操作。但实际上没有真正的进行对象拷贝,直至有其他客户端修改了这个对象Collection。
使用Proxy实现这个方案,这就是copy-on-write操作。
Proxy应用范围很广,现在流行的分布计算方式RMI和Corba等都是Proxy模式的应用。
更多Java设计模式之代理模式(Proxy模式)介绍相关文章请关注PHP中文网!
相关文章: