面向对象编程内功心法系列七(聊一聊单例模式)

1.引子

说起设计模式,做过开发的你一定不会感到陌生,甚至随口都能说上几个。比如单例设计模式、工厂设计模式、建造者设计模式、模板设计模式、策略设计模式、装饰者设计模式、责任链设计模式、观察者设计模式、代理设计模式、适配器设计模式。

你看我一口气就列举了10种常见的设计模式,寓意为十全十美,事实上在gof设计模式中,一共有23种设计模式,细分类为创建型、结构型、行为型设计模式。每一种设计模式都是无数前辈们经验智慧的结晶,都为了解决某一问题域而诞生,实实在在。

今天开始,我想推荐你一起来学习设计模式,不管我们是前端开发工程师,还是后端开发工程师,我觉得都有必要。一来通过学习理解设计模式,有助于提升我们的设计编码内功;二来通过学习理解设计模式,有助于我们在寻找工作机会的时候,与面试官用愉快的心情聊天,不至于尬聊;三嘛当然则是设计模式是我们通往高级工程师,架构师的必备基本技能之一。

那么让我们一起开始吧,今天我们先来聊一聊单例设计模式。

2.案例

2.1.什么是单例设计模式

单例设计模式,重点两个字是单例。我们用更直观的描述则是说,一个类,在整个应用系统中,有且仅有一个实例对象

有关单例设计模式的应用场景,我们试想这样一个需求:全局唯一。每个应用系统都有配置文件,通过配置文件统一配置整个应用环境信息,比如数据库连接信息、缓存redis连接信息等。

在系统启动加载的时候,需要将配置文件内容读取解析存储到内存。从整个应用的角度,配置信息独一无二,我们只需要存储一份就够了。这样带来的好处有,一来方便数据一致性的维护,如果需要修改更新配置信息,只需要维护一份;而来只存储一份,即节省了内存资源开销,省资源。

你看这就是单例设计模式的应用场景,以及它所带来的收益,很好理解对吧。理解了单例设计模式,我们再来看一下如何通过代码实现,talk is cheap, show me you code!

关於单例设计模式,有两种实现方式:饿汉式、以及懒汉式。我们都一起来看一下如何实现。都比较简单,我就直接上代码了,代码中我配备了相关注释,相信你一看就都能明白。

2.2.饿汉式实现单例设计模式

/**
 * 单例设计模式:
 * 1.一个类,在整个系统中有且仅有一个对象,称为单例设计模式
 * 2.比如:配置文件信息,在整个系统中只需要一份配置文件,便于实现信息一致性维护,
 * 同时节省内存资源
 * 3.单例设计模式实现方式:饿汉式,懒汉式
 *
 * @author ThinkPad
 * @version 1.0
 * @date 2021/2/21 16:26
 */
public class HungrySingleton {

    public static void main(String[] args) {
        System.out.println("饿汉式实现IdGenerator 生成器:"
                + IdGenerator.getInstance().getId());

    }

    /**
     * 单例设计模式,饿汉式实现Id生成器
     */
    static class IdGenerator{
        private AtomicInteger id = new AtomicInteger(0);
        /**
         * 饿汉式,创建对象线程安全
         */
        private static IdGenerator instance = new IdGenerator();

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

        /**
         * 提供公有的静态方法,获取实例
         * @return
         */
        public static IdGenerator getInstance(){
            return instance;
        }

        public int getId(){
            return id.incrementAndGet();
        }

    }

}

2.3.懒汉式实现单例设计模式

/**
 * 单例设计模式:
 * 1.一个类,在整个系统中有且仅有一个对象,称为单例设计模式
 * 2.比如:配置文件信息,在整个系统中只需要一份配置文件,便于实现信息一致性维护,
 * 同时节省内存资源
 * 3.单例设计模式实现方式:饿汉式,懒汉式
 *
 * @author ThinkPad
 * @version 1.0
 * @date 2021/2/21 16:43
 */
public class LazySingleton {

    public static void main(String[] args) {
        System.out.println("懒汉式实现IdGenerator 生成器:"
                + IdGenerator.getInstance().getId());
    }

    /**
     * 单例设计模式,懒汉式实现Id生成器
     */
    static class IdGenerator{
        private AtomicInteger id = new AtomicInteger(0);
        /**
         * 懒汉式,支持延迟加载,需要考虑创建对象时线程安全问题
         * volatile关键字,保障内存可见性,及禁止指令重排序
         */
        private static volatile IdGenerator instance;

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

        /**
         * 提供公有的静态方法,获取实例,兼顾线程安全与性能
         * 通过synchronized,与双重检测(double check)保障线程安全
         * @return
         */
        public static IdGenerator getInstance(){
            if(instance == null){
                synchronized (IdGenerator.class){
                    if(instance == null){
                        instance = new IdGenerator();
                    }
                }
            }

            return instance;
        }

        public int getId(){
            return id.incrementAndGet();
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章