zoukankan      html  css  js  c++  java
  • 易学设计模式看书笔记(7)


    代理模式

    1.系统日志记录的样例:给系统中的业务逻辑加上日志
    (1):最简单直接的做法

    public class Test
    {
     private Logger logger = Loger.getLogger(this.getClass().getName());
    
     public void doLgic(String name){
    
      logger.log(name + "開始业务逻辑处理...");
     
      //业务逻辑处理相关程序
      System.out.println("业务逻辑处理相关程序");
      
      logger.log(name + "业务逻辑处理结束...");
     }
    }
    有其它的类的业务逻辑也须要记录日志:
    public class Test1
    {
     private Logger logger = Loger.getLogger(this.getClass().getName());
    
     public void doLgic(String name){
    
      logger.log(name + "開始业务逻辑处理...");
     
      //业务逻辑处理相关程序
      System.out.println("业务逻辑处理相关程序");
      
      logger.log(name + "业务逻辑处理结束...");
     }
    }
    
    


     

    这两个类为了记录日志,在处理业务逻辑的代码中增加了有关日志处理的方法,
    这些方法增加的模式非常相似。混淆了类的单一职责,有什么办法解决问题?

    (2):静态代理

    定义一个有业务逻辑的接口类:
    public interface Test
    {
     public void doLogic(String name);
    }
    详细的逻辑处理类:
    public class TestImpl implements Test
    {
     public void doLogic(){
      System.out.println("业务逻辑处理");
     }
    }
    
    日志代理类:
    public class TestProxy implements Test
    {
     private Logger logger = Loger.getLogger(this.getClass().getName());
     private Test test;
     public TestProxy(Test test){
      this.test = test;
     }
    
     public void doLogic(String name){
      logger.log("開始业务逻辑处理...");
      //业务逻辑处理
      test.doLogic(name);
      logger.log("业务逻辑处理结束...");
     }
    }
    
    调用代理类,实现日志输出:
    
    public class Client
    {
     public static void main(String[] args){
      TestProxy testProxy = new TestProxy(new TestImpl());
      testProxy.doLogic("小四");
     }
    }
    

    通过业务逻辑的代理类来调用详细的业务逻辑,相同实现了日志的记录,
    并且把日志的记录和业务逻辑进行了分离,这是静态代理。
    存在问题就是:每一个方法都要有一个代理类。假设系统中的每一个类都要日志记录,
    那代理类的数量非常多。

    解决的方法就是动态代理了。

    (3):动态代理

    基于JDK的动态代理:

    public LogProxy implements InvocationHandler
    {
     private Logger logger = Loger.getLogger(this.getClass().getName());
     private Object delegate;//代理对象
     
     public Object bind(Object delegate){
      this.delegate = delegate;
      return Proxy.newProxyInstance(delegate.getClass().getClassLoader(),
       delegate.getClass().getInterfaces(),this);
     }
    
     public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
      
      Object result = null;
      try{
       logger.log("開始业务逻辑处理...");
       //业务逻辑处理
       result = method.invoke(delegate,args);
       logger.log("业务逻辑处理结束...");
      }catch(Exception e){
       logger.log(e.toString());
      }
    
      return result;
     }
    }
    
    public class  Client
    {
     public static void main(String[] args) 
     {
      LogProxy logProxy = new LogProxy();
      Test test = (Test)logProxy.bind(new TestImpl());
      test.doLogin("小五");
     }
    }

    JDK的动态代理仅仅能针对接口代理。要实现对类的动态代理能够用cglib的动态代理或者其他类库的。

    一般推荐的是面向接口编程。

    2.动态代理模式简单介绍:
    【定义】
    代理模式就是给一个对象提供一个代理对象。由这个代理对象控制对
    原对象的引用,使代理对象在原对象和client之间起到一个中介的作用。

    【原理】
    代理模式主要由三部分组成:
    抽象目标类,详细目标类 和代理类。

    【使用时机】
    当系统须要对某个对象进行额外的控制时。

  • 相关阅读:
    shell入门-sed-2替换功能
    shell入门-sed-1
    shell入门-grep-3-egrep
    shell入门-grep2
    shell入门-grep过滤-1
    shell入门-连接符(并且、和、或者)
    shell入门-tr替换字符和split切割大文件
    shell入门-uniq去重复和tee重定向
    class类的相关操作 --| 公有普通方法 | 私有普通方法 | 无参方法 | 有参方法
    类的封装性-- | 成员属性 | 成员方法 | 私有属性 | 私有方法 之间调用
  • 原文地址:https://www.cnblogs.com/tlnshuju/p/6894658.html
Copyright © 2011-2022 走看看