设计模式——单例模式

最近系统的看了下设计模式,对于单例又有一些新的理解:

1.单例和静态变量有什么优缺点:

  • 静态变量一般在定义的时候就初始化了(有些语言要求这样),如果不用是一种浪费,而单例一般是延迟实例化(第一次用的时候才实例化),如果要实例化的对象十分消耗内存,那么就要关心这点。
  • 静态变量还是可以被更改的,有时候要靠程序员之间的约定,才能做到唯一(大家都不要动它)。单例天然可以做到这点。

2.单例的各种方式:

(1).最简单的模式(不考虑多线程)

public class Singleton {
    private static Singleton uniqueInstance;
    
    private Singleton () {} // 不允许外界调用构造函数

    public static Singleton getInstance () {
        if ( uniqueInstance == null ) {
            uniqueInstance = new Singleton () ;
        }
        return uniqueInstance;
    }
    // 其他方法
}

 (2).考虑多线程,避免创造出两个对象,把getInstance方法设置成同步方法

public class Singleton {
    private static Singleton uniqueInstance;
    
    private Singleton () {} // 不允许外界调用构造函数

    public static synchronized Singleton getInstance () {
        if ( uniqueInstance == null ) {
            uniqueInstance = new Singleton () ;
        }
        return uniqueInstance;
    }
    // 其他方法
}

 这种方法有个问题:就是同步会降低性能,如果项目会频繁的调用getInstance方法,而又十分的在意性能,那么这样不是一个好方法,如果不是这样,那么这样就可以满足要求。

(3).对于多线程的改善:

A:使用“急切”创建实例,而不用延迟实例化的做法,适用于创建的对象并不是十分耗内存,即时很晚才用到或者压根不用,完全不care。

public class Singleton {
    private static Singleton uniqueInstance = new Singleton () ;
    
    private Singleton () {}
   
    public static Singleton getInstance () {
        return uniqueInstance;
    }
}

 B:利用“双重检查加锁”,在getInstance()中减少使用同步

public class Singleton {
    private volatile static Singleton uniqueInstance;
    
    private Singleton () {}

    public static Singleton getInstance () {
        if (uniqueInstance == null) {
            synchronized (Singleton.class) { // 只有第一次才会走到这里
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton ();
                }
            }
        }
        return uniqueInstance;
    }
}

 *考虑如果实现ios的“双重检查加锁”。

3.其实可以说单例模式违反了“单一职责”的设计原则,因为不只要维护自己先关的功能,还要管理自己的实例化,但是这样可以让整体设计更简单,所以还是那句话,设计原则只不过是要尽量的遵守,不是一定要百分之百不能违背。各种设计模式,都可以思考下,遵守了哪些设计原则,违反了哪些设计原则。

 

posted @ 2016-11-07 21:45  张驰小方块  阅读(227)  评论(0编辑  收藏  举报