zoukankan      html  css  js  c++  java
  • 代理模式

    转自: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("收取手续费,打印发票。。。。。
    ");
        }
    
    }

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

  • 相关阅读:
    一张图片入门Python
    4.1. 如何在Windows环境下开发Python
    你必须知道的EF知识和经验
    XUnit的使用
    如何使用NUnit
    Entity Framework 不支持DefaultValue
    Have You Ever Wondered About the Difference Between NOT NULL and DEFAULT?
    Validation failed for one or more entities. See 'EntityValidationErrors' property for more details
    Entity Framework 与多线程
    sqlite中的自增主键
  • 原文地址:https://www.cnblogs.com/paulbai/p/5768365.html
Copyright © 2011-2022 走看看