设计模式学习(三) — 结构型模式

设计模式学习(三) — 结构型模式

结构型模式主要是侧重于类之间结构构建的设计经验总结
个人主页:tuzhenyu’s page
原文地址:设计模式学习(三) — 结构型模式

(0) 基本概念

  • 结构型设计模式侧重于类之间的结构构建,用来解决模块之间的耦合问题;

  • 结构型设计模式主要包括装饰器模式,适配器模式,代理模式等;

(1) 装饰器模式

  • 装饰器模式是动态地给一个对象添加一些额外的功能,把核心功能和装饰功能区分开来更好的控制对象功能;

  • 装饰器功能的好处:

    • 将特定的装饰功能封装到一个类中用于包装核心功能的类,这样可以有选择有顺序的定制特定功能的对象;

    • 将核心功能和装饰功能区分开来,去除相关类中重复的装饰逻辑,同时也降低核心功能和装饰功能的耦合度;

Mybatis中的装饰器模式

  • 在MyBatis中具体的SQL命令执行是通过Executor完成的,如果在配置文件转中开启Cache缓存功能则在生成Executor实例时通过装饰器模式将Executor核心类包装成CachingExecutor增加缓存功能;



public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
    executorType = executorType == null?this.defaultExecutorType:executorType;
    executorType = executorType == null?ExecutorType.SIMPLE:executorType;
    Object executor;
    if(ExecutorType.BATCH == executorType) {
        executor = new BatchExecutor(this, transaction);
    } else if(ExecutorType.REUSE == executorType) {
        executor = new ReuseExecutor(this, transaction);
    } else {
        executor = new SimpleExecutor(this, transaction);
    }

    //装饰器模式添加缓存功能
    if(this.cacheEnabled) {
        executor = new CachingExecutor((Executor)executor);
    }

    Executor executor1 = (Executor)this.interceptorChain.pluginAll(executor);
    return executor1;
}
  • 带有缓存功能的执行类CachingExecutor在执行具体的SQL指令时会执行装饰逻辑同时也会将指令转发给核心执行类SimpleExecutor;



public int update(MappedStatement ms, Object parameterObject) throws SQLException {
  flushCacheIfRequired(ms);
  return delegate.update(ms, parameterObject);
}

Collectios中的装饰器模式

  • Collections工具类中将普通集合类转化成线程安全的集合类是通过装饰器模式,比如Collections.synchronizedList(),Collections.synchronizedMap()等;

  • 调用Collections工具类方法创建装饰器类,功能的实现仍是通过传入的参数普通集合类只是在方法外加上一层synchronized锁;


public E get(int index) {
    synchronized (mutex) {return list.get(index);}
}

Java IO中的装饰器模式

  • BufferedInputStream,DataInputStream等都是在原始数据流基础上添加新的功能,BufferedInputStream用来从硬盘将数据读入到一个内存缓冲区中,并从缓冲区提供数据;DataInputStream提供基于多字节的读取方法,可以读取原始类型的数据。

(2) 适配器模式

  • 适配器模式是将一个类的接口转换成期望类的接口,让原本不兼容的类可以一起工作

  • 适配器模式的主要优点是将目标类和适配者类解耦,增加了类的透明性和复用性,同时系统的灵活性和扩展性都非常好,更换适配器或者增加新的适配器都非常方便

Java IO中的适配器模式

  • ByteArrayInputStream是Java IO中适配器模式的使用,将内存中的数组转化成数据流从而能够进行流处理

try  
        {  
            DataInputStream in = new DataInputStream(new ByteArrayInputStream(BufferedInputFile.read("MemoryInput.java").getBytes()));  
            while(true)  
            {  
                System.out.print((char)in.readByte());      
            }             
        }  
        catch (EOFException e)  
        {  
            System.err.println("End Of Stream");  
        }  

(3) 代理模式

  • 给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问,即客户不直接操控原对象,而是通过代理对象间接地操控原对象。

  • 代理模式和装饰器模式区别:代理类(proxy class)可以对它的客户隐藏一个对象的具体信息。因此,当使用代理模式的时候,我们常常在一个代理类中创建一个对象的实例。并且,当我们使用装饰器模 式的时候,我们通常的做法是将原始对象作为一个参数传给装饰者的构造器。

代理模式的使用情景

  • Spring中AOP功能的实现核心就是动态代理,在装载Bean时根据配置文件判断是否生成相应的代理类实例;

  • RPC中通过代理模式是对底层远程调用过程进行隐藏,使客户端调用方法时和调用普通方法一样;

总结

结构型设计模式主要是在特定情况下对类与类之间的结构进行构建,根据具体的情况可以单独使用或者组合使用装饰器模式,适配器模式,代理模式等;

你可能感兴趣的:(java,设计模式)