大话设计模式三:单例模式

一.模式定义

    单例模式是日常开发中用到最多的一种设计模式。

Ensure a class has only one instance and provide a global point of access to it.

单例模式可以确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,

 

二.模式要素

    单例Singleton

 

三.举例说明

    一个典型的例子就是居民身份证的例子。每个人在出生后都会分配一张身份证,身份证上的号码是唯一的,以后即使迁转户口,证件丢失,新办理的身份证依旧还是使用之前的号码。

 

四.模式实例

1.懒汉模式

/**
 * @program: DesignModes
 * @description: Main
 * @author: Lei Dong
 * @create: 2018-09-20 22:26
 **/
public class Main {
    public static void main(String[] args) {
        Singleton1 singleton1 = Singleton1.getInstance();
        singleton1.showInfo();
    }
}

/**
 * 懒汉
 */
class Singleton1 {
    private static Singleton1 instance;

    private Singleton1() {

    }

    public static Singleton1 getInstance() {
        if(instance == null) {
            instance = new Singleton1();
        }
        return instance;
    }

    void showInfo() {
        System.out.println("我是懒汉模式");
    }
}

运行结果

 

2.饿汉模式

/**
 * @program: DesignModes
 * @description: Main
 * @author: Lei Dong
 * @create: 2018-09-20 22:26
 **/
public class Main {
    public static void main(String[] args) {
        Singleton2 singleton1 = Singleton2.getInstance();
        singleton1.showInfo();
    }
}

/**
 * 饿汉
 */
class Singleton2 {
    private static Singleton2 instance = new Singleton2();

    private Singleton2() {

    }

    public static Singleton2 getInstance() {
        return instance;
    }

    void showInfo() {
        System.out.println("我是饿汉模式");
    }
}

运行结果:

 

3.双检锁模式

/**
 * @program: DesignModes
 * @description: Main
 * @author: Lei Dong
 * @create: 2018-09-20 22:26
 **/
public class Main {
    public static void main(String[] args) {
        Singleton3 singleton3 = Singleton3.getInstance();
        singleton3.showInfo();
    }
}

/**
 * 双检锁
 */
class Singleton3 {
    private static volatile Singleton3 instance;

    private Singleton3() {

    }

    public static Singleton3 getInstance() {
        if (instance == null) {
            synchronized (Singleton3.class) {
                if (instance == null) {
                    instance = new Singleton3();
                }
            }
        }
        return instance;
    }

    void showInfo() {
        System.out.println("我是双检锁模式");
    }
}

运行结果:

 

4.静态内部类模式

/**
 * @program: DesignModes
 * @description: Main
 * @author: Lei Dong
 * @create: 2018-09-20 22:26
 **/
public class Main {
    public static void main(String[] args) {
        Singleton4 singleton4 = Singleton4.getInstance();
        singleton4.showInfo();
    }
}

/**
 * 静态内部类
 */
class Singleton4 {
    private Singleton4() {

    }

    private static class Holder {
        private static final Singleton4 INSTANCE = new Singleton4();
    }

    public static Singleton4 getInstance() {
        return Holder.INSTANCE;
    }

    void showInfo() {
        System.out.println("我是静态内部类模式");
    }
}

运行结果:

 

五.总结

1.单例模式的优点
(1) 提供了对唯一实例的受控访问。因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它,并为设计及开发团队提供了共享的概念。
(2)由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象,单例模式无疑可以提高系统的性能。
(3)允许可变数目的实例。我们可以基于单例模式进行扩展,使用与单例控制相似的方法来获得指定个数的对象实例。

2.单例模式的缺点
(1) 由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。
(2)单例类的职责过重,在一定程度上违背了“单一职责原则”。因为单例类既充当了工厂角色,提供了工厂方法,同时又充当了产品角色,包含一些业务方法,将产品的创建和产品的本身的功能融合到一起。
(3)滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;现在很多面向对象语言(如Java、C#)的运行环境都提供了自动垃圾回收的技术,因此,如果实例化的对象长时间不被利用,系统会认为它是垃圾,会自动销毁并回收资源,下次利用时又将重新实例化,这将导致对象状态的丢失。

2.单例模式的适用环境
在以下情况下可以使用单例模式:
(1) 系统只需要一个实例对象,如系统要求提供一个唯一的序列号生成器,或者需要考虑资源消耗太大而只允许创建一个对象。
(2)客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。
(3)在一个系统中要求一个类只有一个实例时才应当使用单例模式。反过来,如果一个类可以有几个实例共存,就需要对单例模式进行改进,使之成为多例模式。

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值