zoukankan      html  css  js  c++  java
  • 23种设计模式----------代理模式(二)

    (上一篇)23种设计模式----------代理模式(一)

    之前说了基本的代理模式和普通代理模式。接下来开始看下强制代理模式和虚拟代理模式

    三,强制代理模式:

    一般的代理模式都是通过代理类找到被代理的对象,从而调用被代理类中的方法(即完成被代理类中的任务)。

    而,强制代理模式则是先找到被代理类自己去完成事情,然后被代理类又将该做的事情转交到代理类中,让代理类来完成。

    假如:你有事求助于某位名人。

    你告诉名人说有事想请他帮忙,然后他说最近一段时间比较忙,要不你找我的经纪人来办吧。

    (本来找名人办事,事情由他来完成的,即 表示 真实主题类。然而,他要将事情转交给自己的经纪人(即代理类),这时该名人就是被代理者)。

    代码实现如下

    抽象主题类或者接口:

     1 package com.yemaozi.proxy.force;
     2 
     3 public interface IGamePlayer {
     4     //登录游戏
     5     public void login(String username, String password);
     6     
     7     //击杀Boss
     8     public void killBoss();
     9     
    10     //升级
    11     public void upGrade();
    12     
    13     //获取代理
    14     public IGamePlayer getProxy();
    15 }
    16 //由于要通过主题类找代理类,所以在此添加getProxy()方法,获取代理。

    需要被代理类:

     1 package com.yemaozi.proxy.force;
     2 
     3 public class GamePlayer implements IGamePlayer{
     4     private String name = "";
     5 
     6     private IGamePlayer proxyGp = null;
     7     
     8     public GamePlayer(String name){
     9         this.name = name;
    10     }
    11 
    12     //获取代理。
    13     public IGamePlayer getProxy() {
    14         this.proxyGp = new ProxyGamePlayer(this);
    15         return this.proxyGp;
    16     }
    17 
    18     public void login(String username, String password) {
    19         //只有是自己指定的代理人才给办事,别人的代理也不搭理咱啊,所以判断是否为自己的代理,若是,则正常执行。
    20         if(this.isProxy()){
    21             System.out.println("登录名为 "+username+" 进入游戏," + name + " 登录成功!");
    22         }else{
    23             System.out.println("请使用制定代理访问!");
    24         }
    25     }
    26 
    27     public void killBoss() {
    28         if(this.isProxy()){
    29             System.out.println(this.name + " 击杀了Boss!");
    30         }else{
    31             System.out.println("请使用制定代理访问!");
    32         }
    33     }
    34 
    35 
    36     public void upGrade() {
    37         if(this.isProxy()){
    38             System.out.println(this.name + "升级了!");
    39         }else{
    40             System.out.println("请使用制定代理访问!");
    41         }
    42     }
    43     
    44     //判断是否是代理
    45     public boolean isProxy(){
    46         if(this.proxyGp!=null){
    47             return true;
    48         }else {
    49             return false;
    50         }
    51     }
    52     
    53 }

    代理类:

     1 package com.yemaozi.proxy.force;
     2 
     3 //强制代理的代理类。
     4 public class ProxyGamePlayer implements IGamePlayer{
     5     
     6     private IGamePlayer proxyGp = null;
     7     
     8     public ProxyGamePlayer(IGamePlayer gp){
     9         this.proxyGp = gp;
    10     }
    11     
    12     public void login(String username, String password) {
    13         System.out.println("代理登录游戏!");
    14         this.proxyGp.login(username, password);
    15     }
    16 
    17     public void killBoss() {
    18         this.proxyGp.killBoss();
    19     }
    20 
    21 
    22     public void upGrade() {
    23         this.proxyGp.upGrade();
    24     }
    25 
    26     public IGamePlayer getProxy() {
    27         return this;
    28     }
    29 }

    这次设计的是只有自己指定的代理类才能正常执行方法。

    场景类一:不通过代理来执行。

     1 package com.yemaozi.proxy.force;
     2 
     3 public class Client {
     4     public static void main(String[] args) {
     5         
     6         IGamePlayer gp = new GamePlayer("张三");
     7         
     8         gp.login("zhangsan", "123456");
     9         gp.killBoss();
    10         gp.upGrade();
    11     }
    12 }
    13 
    14 执行结果:
    15 请使用制定代理访问!
    16 请使用制定代理访问!
    17 请使用制定代理访问!
    18 
    19 //很显然,不用代理,是不能正常执行。

    场景类二:用不是指定的代理类来执行。

     1 package com.yemaozi.proxy.force;
     2 
     3 //直接访问代理类(非真实用户制定的代理)
     4 public class ProxyClient {
     5     public static void main(String[] args) {
     6         IGamePlayer proxy = new ProxyGamePlayer(new GamePlayer("张三"));
     7         
     8         proxy.login("zhangsan", "123456");
     9         proxy.killBoss();
    10         proxy.upGrade();
    11     }
    12 }
    13 
    14 执行结果:
    15 代理登录游戏!
    16 请使用制定代理访问!
    17 请使用制定代理访问!
    18 请使用制定代理访问!
    19 
    20 //显然虽然代理登录了,但是由于是非法的(有可能属于盗号行为),所以下面还是执行不了。

    场景类三:使用真实主题类指定的代理。

     1 package com.yemaozi.proxy.force;
     2 
     3 //通过真是类去访问代理类。
     4 public class SpecificProxyClient {
     5     public static void main(String[] args) {
     6         IGamePlayer gp = new GamePlayer("张三");
     7         IGamePlayer proxyGp = gp.getProxy();
     8         
     9         proxyGp.login("zhangsan", "123456");
    10         proxyGp.killBoss();
    11         proxyGp.upGrade();
    12     }
    13 }
    14 
    15 执行结果:
    16 代理登录游戏!
    17 登录名为 zhangsan 进入游戏,张三 登录成功!
    18 张三 击杀了Boss!
    19 张三升级了!
    20 
    21 //这次终于可以顺利的执行了。

    强制代理模式的概念就是要从真是角色那里查找到代理角色,不允许直接访问真实角色。上层模块只需要调用getProxy()获取代理来访问真实角色的所有方法,它根本就不需要产生一个代理角色,代理的管理已经由真实角色自己来完成。

    四,虚拟代理模式:

    虚拟代理:其实就是在需要的时候再初始化主题角色。

      1,优点:可以避免被代理对象过多,而带来的初始化缓慢。

      2,缺点:需要在每个方法上判断主题对象是否被创建。

    代码实现如下

    抽象主题类或者接口:

     1 package com.yemaozi.proxy.virtual;
     2 
     3 //虚拟代理:就是需要初始化的时候才进行初始化主题    
     4 //优点:可以避免由于被代理对象过多,而引起的初始化缓慢的问题,
     5 //缺点:需要在每个方法中判断对象主题是否已被创建。
     6 public interface IGamePlayer {
     7     //登录游戏
     8     public void login(String username, String password);
     9     
    10     //击杀Boss
    11     public void killBoss();
    12     
    13     //升级
    14     public void upGrade();
    15 }

    需要被代理的类:

     1 package com.yemaozi.proxy.virtual;
     2 
     3 public class GamePlayer implements IGamePlayer {
     4 
     5     private String name = "";
     6     
     7     public GamePlayer(String name){
     8         this.name = name;
     9     }
    10     
    11     public void login(String username, String password) {
    12         System.out.println("登录名为 "+username+" 进入游戏," + name + " 登录成功!");
    13     }
    14         
    15     public void killBoss() {
    16         System.out.println(this.name + " 击杀了Boss!");
    17     }
    18 
    19     public void upGrade() {
    20         System.out.println(this.name + "升级了!");
    21     }
    22 
    23 }

    代理类:

     1 package com.yemaozi.proxy.virtual;
     2 
     3 public class ProxyGamePlayer implements IGamePlayer {
     4 
     5     //声明要代理的对象。
     6     private IGamePlayer gp;
     7     
     8     public void login(String username, String password) {
     9         //都需要判断真实主题类的存在与否。
    10         if(gp==null){
    11             gp = new GamePlayer("张三");
    12         }
    13         gp.login(username, password);
    14     }
    15 
    16     public void killBoss() {
    17         //都需要判断真实主题类的存在与否。
    18         if(gp==null){
    19             gp = new GamePlayer("张三");
    20         }
    21         gp.killBoss();
    22     }
    23 
    24     public void upGrade() {
    25         //都需要判断真实主题类的存在与否。
    26         if(gp==null){
    27             gp = new GamePlayer("张三");
    28         }
    29         gp.upGrade();
    30     }
    31 }

    (下一篇)种设计模式----------代理模式(三)

  • 相关阅读:
    Redis详解(一)——RDB
    十、行锁
    go 上下文context
    go log
    go 结构体取代类
    go select
    go channel
    go 协程(Goroutine)
    go 学习之fmt包
    go 学习之bufio
  • 原文地址:https://www.cnblogs.com/yemaozistar/p/4162025.html
Copyright © 2011-2022 走看看