设计模式之单例模式

  1. 单例模式概念:Ensure a class has only one instance,and provide a global point of access to it.即是确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
    单例模式的通用代码:
package singleton;
/**
 *@author xpengfei
 *@creat  8:04:31 PM   Oct 9, 2017
 *单例模式的通用代码
 *饿汉式单例
 */
public class Singleton {
    //自行实例化一个对象
    private static final Singleton singleton=new Singleton();
    //限制产生多个对象
    private Singleton(){}
    //编写get方法获取实例对象
    public static Singleton getSingleton(){
        return singleton;
    }
    //类中的其他static方法
    public static void dosomething(){}
}

2.示例:
皇帝类设置为单例模式,则产生的对象只有一个。

package singleton;
/**
 *@author xpengfei
 *@creat  7:51:53 PM   Oct 9, 2017
 *皇帝类,单例类
 */
public class Emperor {
    //初始化一个对象
    private static final Emperor emperor=new Emperor();
    //将该类的构造函数设置为私有,不允许外部类调用构造函数创建对象
    private Emperor(){}
    //静态方法获取该类的对象
    public static Emperor getInstance(){
        return emperor;
    }
    //静态方法
    public static void say(){
        System.out.println("aaaaaaaaa");
    }
}

臣子类中三次循环所获取的皇帝对象是同一个对象

package singleton;
/**
 *@author xpengfei
 *@creat  7:52:05 PM   Oct 9, 2017
 */
public class Minister {
    public static void main(String[] args) {
        for(int i=0;i<3;i++){
            Emperor e=Emperor.getInstance();
            e.say();
        }
    }
}

3.单例模式的优点:
- 由于单例模式中只有一个对象,所以减少了内存开支,特别是一个对象需要频繁的创建、销毁的时候,而且对象的创建或销毁的时候性能又无法进行优化。
- 减少了系统的性能开销,当一个对象的产生需要比较多的资源的时候,例如:读取配置、产生其它依赖对象时,可以通过单例模式用永久驻留内存的方式解决(JavaEE中采用单例模式需要注意JVM垃圾回收机制)。
- 单例模式可以避免对资源的多重占用,例如:一个写文件动作,由于只有一个实例在内存中,避免了对同一个资源文件的同时写操作。
- 单例模式可以在系统设置全局的访问点,优化和共享资源访问。例如:可以设计一个单例类,负责所有数据表的映射处理。
4.单例模式的缺点:
- 单例模式一般没有接口,扩展很难,想要扩展的话只有修改代码。
- 单例模式对测试不利。在并发环境中,如果单利模式没有完成,是不能进行测试的,没有接口也不能使用mock的方式虚拟一个对象。
- 单例模式与单一职责原则有冲突。
5.单例模式使用场景:
- 要求生成唯一序列号的环境。
- 在整个项目中需要一个共享访问点或共享数据,例如:web页面上的计数器,可以不用每次都把刷新的记录放到数据库中,使用单例模式保持计数器的值,并确保是线程安全的。
- 创建一个对象需要消耗的资源过多,例如:访问IO和数据库等资源。
- 需要定义大量的静态常量和静态方法的方法(如工具类),可以采用单例模式(也可以直接声明为static方法)。
6.懒汉式单例:

package singleton;
/**
 *@author xpengfei
 *@creat  8:04:31 PM   Oct 9, 2017
 *懒汉式单例
 */
public class Singleton {
    //自行实例化一个对象
    private static Singleton singleton=null;
    //限制产生多个对象
    private Singleton(){}
    //编写get方法获取实例对象
    public static synchronized Singleton getSingleton(){
        if(singleton==null){
            singleton=new Singleton();
        }

        return singleton;
    }
    //类中的其他static方法
    public static void dosomething(){}
}

7.单例模式的扩展:
可以将单例模式扩展为产生实例数量有限的形式:

Emperor类中设置了最多能产生的实例的个数:

package singleton;

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

/**
 *@author xpengfei
 *@creat  7:51:53 PM   Oct 9, 2017
 *皇帝类,单例类
 */
public class Emperor {
    //定义最多能产生的实例数量
    private static int maxNumOfEmperor=5;
    //每一个对象都有名字,使用list存储
    private static ArrayList<String>namelist=new ArrayList<>();
    //定义一个列表存储所有的实例对象
    private static ArrayList<Emperor>emperorlist=new ArrayList<>();
    //当前对象序列号
    private static int countNumOfEmperor=0;
    //产生所有的对象
    static {
        for (int i = 0; i < maxNumOfEmperor; i++) {
            emperorlist.add(new Emperor("第"+(i+1)+"个皇帝"));
        }
    }
    //将该类的构造函数设置为私有,不允许外部类调用构造函数创建对象
    private Emperor(String name){
        namelist.add(name);
    }

    //静态方法获取该类的对象
    public static Emperor getInstance(){
        Random random=new Random();
        //随机取出一个皇帝对象
        countNumOfEmperor=random.nextInt(maxNumOfEmperor);
        return emperorlist.get(countNumOfEmperor);
    }
    //静态方法
    public static void say(){
        System.out.println(namelist.get(countNumOfEmperor));
    }
}

Minister类中随机访问

package singleton;
/**
 *@author xpengfei
 *@creat  7:52:05 PM   Oct 9, 2017
 */
public class Minister {
    public static void main(String[] args) {
        for(int i=0;i<10;i++){
            Emperor e=Emperor.getInstance();
            System.out.print("第"+(i+1)+"个大臣参拜的是:");
            e.say();
        }
    }
}

结果如下:
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值