设计模式——单例模式

单例模式:Singleton

单例模式英文定义:

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

单例模式中文定义:

确保一个类只有一个实例,而且自行实例化并向整个应用提供这个实例。

单例模式优点:

1、在内存中只有一个实例,减少了内存开支;

2、只生成一个实例,减少了系统的性能开销;

3、可以避免对资源的多重占用;

4、可以在系统设置全局的访问点,优化和共享资源访问,比如数据库的映射处理。

单例模式缺点:

1、单例模式要求“自行实例化”并提供单一实例,接口或抽象类不能被实例化,所以单例模式一般没有接口,扩展很困难,只能通过修改代码来实现。当然,在特殊情况下,单例模式可以实现接口或被继承,这个根据具体开发环境判断。

2、单例模式与单一职责原则冲突。单一职责原则规定:一个类应该只实现一个逻辑,而不关心它是否是单例的,而单例模式则把“要单例”和业务逻辑融合了一个类中处理。

单例模式使用场景:

1、要求生成唯一序列号时;

2、需要定义大量的静态常量和静态方法(比如工具类)时;

3、创建一个对象需要消耗的资源过多时;

4、在整个项目中需要一个共享访问点或共享数据时。

单例模式通用方法:

饿汉式单例模式:

package com.hongke;

/**
 * @author chengjunyu
 * @classname Singleton
 * @description 饿汉式单例模式
 * @date 2020/8/1 15:38
 */
public class Singleton {

    private static final Singleton singleton = new Singleton();
    //通过private修饰词限制产生多个对象
    private Singleton() {

    }
    //通过该方法获取一个单例对象,此处使用的是【饿汉式单例模式】
    public static Singleton  getSingleton() {
        return singleton;
    }
    //单例模式要处理的业务
    public void doSomething() {
        System.out.println("我是饿汉式单例模式");
    }
}

懒汉式单例模式:

package com.hongke;

/**
 * @author chengjunyu
 * @classname Singleton
 * @description 懒汉式单例模式
 * @date 2020/8/1 15:38
 */
public class Singleton {

    private static Singleton singleton = null;
    //通过private修饰词限制产生多个对象
    private Singleton() {

    }
    //通过该方法获取一个单例对象,此处使用的是【懒汉式单例模式】
    public static Singleton  getSingleton() {
        if(null == singleton) {
            singleton = new Singleton();
        }
        return singleton;
    }
    //单例模式要处理的业务
    public void doSomething() {
        System.out.println("我是懒汉式单例模式");
    }
}

单例模式使用注意事项:

单例模式分为【饿汉式单例模式】和【懒汉式单例模式】,低并发的情况下两者一致,高并发情况下使用懒汉式单例模式可能会导致线程不安全。因此建议使用饿汉式单例模式,当然,也可以通过synchronized关键字去修饰懒汉式单例模式中的getSingleton()方法,不过这种方式明显不如饿汉式单例模式来的方便。

单例模式示例:

很多公司的老板或创始人只有一位,比如说华为创始人,我们都知道就是任正非先生,现在华为发布了一款新的产品,记者来到了华为公司进行采访,并且表示要采访华为创始人任正非先生,那么在程序中便可通过以下案例进行。

Boss.java

package com.hongke;

/**
 * @author chengjunyu
 * @classname Boss
 * @description 老板单例类
 * @date 2020/8/1 14:50
 */
public class Boss {
    private static String bossName = "任正非";
    private static final Boss boss = new Boss();
    private Boss() {

    }
    public static Boss getInstance() {
        return boss;
    }
    public void say() {
        System.out.println("我是华为创始人:" + bossName);
    }
}

Reporter.java

package com.hongke;

/**
 * @author chengjunyu
 * @classname Reporter
 * @description 记者类
 * @date 2020/8/1 14:54
 */
public class Reporter {
    public static void main(String[] args) {
        Boss boss = Boss.getInstance();
        boss.say();
    }
}

打印结果如下:

单例模式扩展:

在一些特殊场景下,需要一个类能产生固定数量的对象。比如说华为的轮值董事长,目前是郭平、徐直军、胡厚崑,每个轮值董事长管理华为一段时间,但他们都是华为的轮值董事长。此时,华为又发布了一款新产品,记者又来采访了,这次他们不再去麻烦任正非先生了,他们就去找了华为的轮值董事长,但他们并不挑剔,只要是华为的轮值董事长,对他们来说都是可以的,那么在程序中便可通过以下案例进行。

RotatingChairman.java

package com.hongke;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * @author chengjunyu
 * @classname RotatingChairman
 * @description 轮值董事长
 * @date 2020/8/1 17:00
 */
public class RotatingChairman {
    //轮值董事长名称
    private static List<String> nameList = new ArrayList<>();
    //轮值董事长集合列表
    private static List<RotatingChairman> chairmanList = new ArrayList<>();
    //轮值董事长序号
    private static int numberOfChairman = 0;
    //静态方法中直接创建三位轮值董事长
    static {
        chairmanList.add(new RotatingChairman("郭平"));
        chairmanList.add(new RotatingChairman("徐直军"));
        chairmanList.add(new RotatingChairman("胡厚崑"));
    }
    private RotatingChairman() {

    }
    private RotatingChairman(String name) {
        nameList.add(name);
    }
    //随机出现一位轮值董事长
    public static RotatingChairman getRotatingChairman() {
        Random random = new Random();
        numberOfChairman = random.nextInt(chairmanList.size());
        return chairmanList.get(numberOfChairman);
    }
    public void say() {
        System.out.println("我是华为轮值董事长:"+nameList.get(numberOfChairman));
    }
}

Reporter.java

package com.hongke;

/**
 * @author chengjunyu
 * @classname Reporter
 * @description 记者类
 * @date 2020/8/1 14:54
 */
public class Reporter {
    public static void main(String[] args) {
//        Boss boss = Boss.getInstance();
//        boss.say();
        //来了10个记者
        for(int i = 0; i < 10; i++) {
            RotatingChairman rotatingChairman = RotatingChairman.getRotatingChairman();
            rotatingChairman.say();
        }
    }
}

打印结果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值