《研磨设计模式》读书笔记之:适配器模式、单例模式

前言:本篇系看完《研磨设计模式》一书的个人理解和总结,可能存在不正确的地方,看时需要持怀疑态度。另外,所有的图都是示意图,示意,示。

适配器模式(Adaptor):

几点解释:

  1. 本质:功能已经实现了,但是接口不匹配,中间加一层适配器类,通过转调的方式,将已有的功能匹配到特定的接口上。
  2. 客户端使用的是 接口A, 功能A,同时已经存在了功能B,只是接口和客户端使用的 A接口不一致。此时,不想客户端改动代码,也不想改动功能B的实现代码,那就需要在中间加一层 适配器类Adaptor,实现接口 A 并持有一个B的实例,Adaptor中的那些方法最终需要转调 B实例的方法,从而 将B接口的功能适配到 A接口上。
  3. 适配适配,其实就是已有的东西不匹配,需要加个中间者来连接两端。这其实在我们的生活中也会经常用到,电脑上各种的转接线,就是现实生活中的硬件适配器。
  4. 有的时候,某些类库可能很早就有了,后来又多了几个类库,几个类库给出了同一类型业务的不同处理,外观差别很大,为了我们可以以一种统一的方式使用这些类库,我们可以定义或者以某个类库的接口为标准,将其他的类库通过适配器的方式适配到同一个接口上,这样统一了几个类库的外观。当然,这种情况很少见,我们的前人在设计的时候很好的遵循了面向接口编程的思想,大多数时候都是先定义好接口,之后大家给出不同的实现。

单例模式(Singleton):

说明: 因为在 JVM中通过 类加载器实例和类实例 来唯一确定一个 实例,即 Java中的单例是  类加载器级别的。

下面按照下列顺序依次给出单例的Java实现:饿汉、懒汉、双重检查锁、私有内部类、枚举

饿汉模式:

public class Singleton {

    /**
     * 在 类加载的 init阶段初始化,由JVM来保证只会初始化一次
     */
    private static Singleton singleton = new Singleton();

    /**
     * 构造方法私有 无法从外部创建实例
     */
    private Singleton(){
    }

    /**
     * 全局唯一访问点
     * @return Singleton
     */
    public static Singleton getInstance(){
        return singleton;
    }
    
}

分析:在 类被加载时就已经完成了实例的初始化,而不是在 需要时,这点要注意

懒汉模式:

public class Singleton {
    
    private static Singleton singleton = null;

    /**
     * 构造方法私有 无法从外部创建实例
     */
    private Singleton(){
    }

    /**
     * 全局唯一访问点 内置锁同步,不然多线程下会 重复创建
     * @return Singleton
     */
    public static synchronized Singleton getInstance(){
        if (singleton == null){
            singleton = new Singleton();
        }
        return singleton;
    }

}

分析:做到了延迟加载,但是 不管实例有没有被创建,每次都会有加锁和解锁的开销,不合理,性能也不好

双重检查锁(懒汉的优化):

public class Singleton {

    /**
     * 声明为 volatile
     * 不然多线程下,可能会出现线程获取到的实例并未完全初始化
     */
    private static volatile Singleton singleton = null;

    /**
     * 构造方法私有 无法从外部创建实例
     */
    private Singleton(){
    }

    /**
     * 全局唯一访问点
     * @return Singleton
     */
    public static  Singleton getInstance(){
        if (singleton == null){
            synchronized (Singleton.class){
                if (singleton == null){
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }

}

分析:延迟加载,有了实例的情况下不需要再进行 加锁解锁,但是 volatile 的使用还是会有轻微的性能问题,因为每次都会直接操作主内存

私有内部类(比较优雅):

public class Singleton {

    /**
     * 构造方法私有
     */
    private Singleton(){
    }

    private static class SingletonHolder{
        private static Singleton singleton = new Singleton();
    }

    public static Singleton getInstance(){
        return SingletonHolder.singleton;
    }

}

分析:即利用了JVM的类初始化同步机制,又可以在 需要使用的时候才初始化,优雅。

枚举(可能是更合适的单例实现方式):

public enum SingletonEnum {

    /**
     * 某单例
     */
    SOME_INSTANCE;

    private Singleton singleton;

    /**
     * 此方法由JVM在第一次使用枚举类实例 的时候调用
     * 可以看成是 private 外部无法调用
     */
    SingletonEnum(){
        singleton = new Singleton();
    }

    public Singleton getInstance(){
        return this.singleton;
    }


    private class Singleton{
        private Singleton(){
        }

    }
}

分析:利用了 Java对枚举的处理,更简单

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值