设计模式 -代理模式1 - 静态代理模式

静态代理模式

​ 代理模式相当重要,无论生活中还是软件开发中,它使用的频率非常非常高。

1. 什么代理模式

1.1 代理模式详解:

​ 代理在生活非常容易看见:我们买房,购票,出门旅游,结婚,歌手的经纪人等等,这些都是代理。

  • 核心作用
    • 通过代理,控制对对象的访问
      • 可以详细控制访问某个(某类)对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理(即:AOP的微观实现)。从而将同一流程的代码放到代理类中处理。
      • 比如一个流行歌手,一个商家找他做广告,那个流行歌需要和商家进行面谈,合同起草,签字,安排机票等等一系列的安排工作。这只是一个客户时候的工作,但是如果有10个,100个客户呢?歌手是唱歌的,别的事情本来完全没有必要做。那么歌手是不是能够让别人来做呢?这样经纪人或者说代理,就产生了。在以后,如果客户需要找歌手做广告,那么客户就要去找代理或者经纪人,代理或者经纪人做哪些和歌手核心方法无关的哪些事情。到真正需要做歌手唱歌的时候,歌手才去唱歌。而且,代理还可以控制歌手什么时候去拍广告,也可以在歌手拍广告之前做一些前置(面谈,起草合同等)工作,在拍广告后的一些后置处理(收尾款等)。最后,你们发现,经纪人的实际的权利,比明星还大。一个经纪人可能到最后反客为主。在实际开发中,代理也有可能编程非常非常重要的角色。
      • 在这里插入图片描述
  • AOP(Aspect Oriented Programming 面向切片的编程)的核心实现机制。比如在spring等等一些很流行的框架,都用到了面向切片的编程。

2. 静态代理模式中的角色分类

  • 核心角色:

    • 抽象角色 - 公司的规章制度
      • 定义代理角色和真实角色的公共对外方法。
    • 真实角色 - 相当于明星
      • 实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色使用。
      • 关注真正的业务逻辑。
    • 代理角色 - 相当于经纪人
      • 实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑来实现实现抽象方法,并可以附加自己的操作。
      • 将统一的流程控制放到代理角色中处理。
      • 在这里插入图片描述
  • 还是那之前的经纪人和明星的例子来做解释。抽象角色相当于拍广告这个选项(代理角色和真实角色之间的共同点),真实角色相当于明星,而代理角色相当于经纪人。由于明星(真实角色)和经纪人(代理角色)都可以谈拍广告(抽象角色),所以客户过来谈合作的时候,就很好谈。

2. 静态代理模式的实现

​ 静态代理模式,就是代理类有程序员在程序执行之前,已经写完,在程序运行时直接使用的代理类,成为静态代理类。这次以歌手和经纪人之间的关系为例子显示静态代理类。

2.1 经纪人和歌手代理模式的实现

  1. 首先我们要写一个接口,并且经纪人(代理角色)和歌手(真实角色)都必须实现这个接口,以获得统一的方法。

    public interface Star {
        /**
         * 面谈
         */
        void confer();
    
        /**
         * 签合同
         */
        void signContract();
    
        /**
         * 订票
         */
        void bookTicket();
    
        /**
         * 唱歌
         */
        void sing();
    
        /**
         * 收钱
         */
        void collectMoney();
    }
    
  2. 然后,写真实角色,真实角色实现了 Star 这个接口,所以真实角色就拥有 Star 这个接口中定义的行为:

    public class RealStar implements Star {
        public void confer() {
            System.out.println("RealStar.confer()");
        }
    
        public void signContract() {
            System.out.println("RealStar.signContact()");
        }
    
        public void bookTicket() {
            System.out.println("RealStar.bookTicket()");
        }
    
        public void sing() {
            System.out.println("RealStar(周杰伦本人).sing()");
        }
    
        public void collectMoney() {
            System.out.println("RealStar.collectMoney()");
        }
    }
    
  3. 接着,编写代理类,实现 Star 接口的同时必须要注意什么方法是只有真实角色可以完成的,我们需要在代理类中创建一个真实角色对象,以引用只有真实角色可以实现的方法。

    public class ProxyStar implements Star {
    
        // 创建一个 Star 对象
        private Star star;
    	// 可以传入任意一个真实对象,以获得真实角色中的独有方法
        public ProxyStar(Star star) {
            this.star = star;
        }
    
        public void confer() {
            System.out.println("ProxyStar.confer()");
        }
    
        public void signContract() {
            System.out.println("ProxyStar.signContact()");
        }
    
        public void bookTicket() {
            System.out.println("ProxyStar.bookTicket()");
        }
    	// 调用真实角色中的独有的方法,并可以在其前后设置处理方法
        public void sing() {
            System.out.println("设置舞台");
            star.sing();
            System.out.println("拆卸舞台")}
    
        public void collectMoney() {
            System.out.println("ProxyStar.collectMoney()");
        }
    }
    
    
  4. 之后再客户端进行调用就可以了。

    public class Client {
        public static void main(String[] args) {
            Star real = new RealStar();
            Star proxy = new ProxyStar(real);
    
            proxy.confer();
            proxy.signContract();
            proxy.bookTicket();
            proxy.sing();
            proxy.collectMoney();
        }
    }
    

版权声明:本文为qq_41302594原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。