本文是通过阅读《大话设计模式》自身理解总结得出,如果有什么问题,请谅解。
1、在实例化的基础上,应该考虑该实例是否会在多个地方进行同样的操作,实例的内容是否唯一,考虑提取出来。
2、是否需要实例和是否已经实例,应该由控制实例的模块进行自我判断,而不是交由调用者进行判断。
单例模式:
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
疑惑:
对象的实例主要是通过new进行实例化,如果没有编写构造函数,系统也会自动产生空参数的构造函数,那怎么控制在其他模块需要实例化时,保证不
会产生多个实例。
实现:
对象的实例主要通过new,调用构造函数进行,那如果将构造函数的访问级别提高为私有的(private),外界就无法进行访问,进行实例化。这时就会产生
无法实例化对象问题,但是在自身类的方法是可以访问自身类内私有方法,同时类内需要声明一个静态的类变量,用于实例化对象。这就解决了实例化问题,
而这个方法需要是共有的(public),同时是静态的,这样就不需要实例化对象就可以调用,向外界提供接口。针对限制单一实例,可以在这个方法里面进行
判断实例是否已经经过实例,再进行返回。
- public class People{
- private static People p = null;
- private People(){
- }
- public static People getPeople(){
- if(p==null||p.IsDisposed){
- p = new People();
- }
- return p;
- }
- }
注意:如果是在多线程的环境下,就要考虑到锁的设置。
懒汉单例模式:即是上面所介绍的实现方式,这种方式会存在多线程问题,即是线程不安全的做法,可以通过以下方法进行修改
(1)采用双重锁:
- public static People getPeople() {
- if (p== null) {
- synchronized (People.class) {
- if (p == null) {
- p = new People();
- }
- }
- }
- return p;
- }
(2)静态内部类:
- public class People {
- private static class LazyHolder {
- private static final People p = new People();
- }
- private People(){}
- public static final People getPeople() {
- return LazyHolder.p;
- }
- }
饿汉单例模式:
- public class People {
- private People() {}
- private static final People p = new People();
-
- public static People getPeople() {
- return p;
- }
- }
区别:
(1)懒汉是线程不安全(没有经过处理的,最原始的懒汉),饿汉是线程安全的。
(2)懒汉在类加载时,没有实例化对象,即是延迟加载。饿汉在类加载时就实例化了对象。