• 代理模式


    转自:http://blog.csdn.net/luanlouis/article/details/24589193     

       代理模式上,基本上有Subject角色,RealSubject角色,Proxy角色。其中:Subject角色负责定义RealSubject和Proxy角色应该实现的接口;RealSubject角色用来真正完成业务服务功能;Proxy角色负责将自身的Request请求,调用realsubject 对应的request功能来实现业务功能,自己不真正做业务。

          

          上面的这幅代理结构图是典型的静态的代理模式:

           当在代码阶段规定这种代理关系,Proxy类通过编译器编译成class文件,当系统运行时,此class已经存在了。这种静态的代理模式固然在访问无法访问的资源,增强现有的接口业务功能方面有很大的优点,但是大量使用这种静态代理,会使我们系统内的类的规模增大,并且不易维护;并且由于Proxy和RealSubject的功能 本质上是相同的,Proxy只是起到了中介的作用,这种代理在系统中的存在,导致系统结构比较臃肿和松散。

           为了解决这个问题,就有了动态地创建Proxy的想法:在运行状态中,需要代理的地方,根据Subject 和RealSubject,动态地创建一个Proxy,用完之后,就会销毁,这样就可以避免了Proxy 角色的class在系统中冗杂的问题了。

    下面以一个代理模式实例阐述这一问题:

       将车站的售票服务抽象出一个接口TicketService,包含问询,卖票,退票功能,车站类Station实现了TicketService接口,车票代售点StationProxy则实现了代理角色的功能,类图如下所示。

    package com.foo.proxy;
    
    /**
     * 售票服务接口实现类,车站
     * @author louluan
     */
    public class Station implements TicketService {
    
        @Override
        public void sellTicket() {
            System.out.println("
    	售票.....
    ");
        }
    
        @Override
        public void inquire() {
            System.out.println("
    	问询。。。。
    ");
        }
    
        @Override
        public void withdraw() {
            System.out.println("
    	退票......
    ");
        }
    
    }
    package com.foo.proxy;
    /**
     * 售票服务接口 
     * @author louluan
     */
    public interface TicketService {
    
        //售票
        public void sellTicket();
        
        //问询
        public void inquire();
        
        //退票
        public void withdraw();
        
    }
    package com.foo.proxy;
    
    /**
     * 车票代售点
     * @author louluan
     *
     */
    public class StationProxy implements TicketService {
    
        private Station station;
    
        public StationProxy(Station station){
            this.station = station;
        }
        
        @Override
        public void sellTicket() {
    
            // 1.做真正业务前,提示信息
            this.showAlertInfo("××××您正在使用车票代售点进行购票,每张票将会收取5元手续费!××××");
            // 2.调用真实业务逻辑
            station.sellTicket();
            // 3.后处理
            this.takeHandlingFee();
            this.showAlertInfo("××××欢迎您的光临,再见!××××
    ");
    
        }
    
        @Override
        public void inquire() {
            // 1做真正业务前,提示信息
            this.showAlertInfo("××××欢迎光临本代售点,问询服务不会收取任何费用,本问询信息仅供参考,具体信息以车站真实数据为准!××××");
            // 2.调用真实逻辑
            station.inquire();
            // 3。后处理
            this.showAlertInfo("××××欢迎您的光临,再见!××××
    ");
        }
    
        @Override
        public void withdraw() {
            // 1。真正业务前处理
            this.showAlertInfo("××××欢迎光临本代售点,退票除了扣除票额的20%外,本代理处额外加收2元手续费!××××");
            // 2.调用真正业务逻辑
            station.withdraw();
            // 3.后处理
            this.takeHandlingFee();
    
        }
    
        /*
         * 展示额外信息
         */
        private void showAlertInfo(String info) {
            System.out.println(info);
        }
    
        /*
         * 收取手续费
         */
        private void takeHandlingFee() {
            System.out.println("收取手续费,打印发票。。。。。
    ");
        }
    
    }

    代理模式可以起到保护的作用,也可以进行拓展,增强额外的功能。比如上面的例子有一个退票队列,存放乘客的退票车票。当接受订票请求时,先判退票队列里有没有,如果有,取出一张给乘客,无需再调用真实的订票接口;如果退票队列里没有,再调用真实订票接口。

  • 相关阅读:
    macOS 上配置 Lua
    Oracle.ManagedDataAccess.dll
    offer
    Costura.Fody
    日志系统
    实战框架ABP
    什么是算法?
    HTTP状态码->HTTP Status Code
    How to untar a TAR file using Apache Commons
    python实践3:cursor() — 数据库连接操作
  • 原文地址:https://www.cnblogs.com/paulbai/p/5768365.html
Copyright © 2020-2023  润新知