最近复习软考时发现一个有趣的现象。很多设计模式都没有对构造函数做过多的修改。但是单例模式是个意外。
下面来看看单例模式的代码
public class Singleton{
private static Singleton unique = null;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(unique == null){
unique = new Singleton();
}
}
}
那么问题来了。
问题1:单例模式为什么要这么处理构造函数。
问题2:单例模式如何解决私有化构造函数的弊端
问题3:这样做的弊端是什么
首先来看第一个问题。单例模式将构造函数私有化,所以我们无法公开使用构造函数。也就是说像Singleton a = new Singleton()这样的写法是无法得到实例的。那么为什么要这么做呢。那是因为单例模式的定义是保证一个类仅有一个实例,并提供一个访问它的全局访问点。而一个类能够被创建多个实例,问题的根源在于类的构造方法是公开的,也就是可以让类的外部来通过构造方法来创建多个实例。因此需要把创建实例的权限尽可能地缩小,甚至取消。
现在来看看问题二。既然构造函数是创建类时使用的,那么取消了类的创建权限,我们该如何创建类呢?在单例模式中提供一个创建类的静态方法,来供大家创建时使用。这两种方法的差别在于构造方法无法处理静态变量而特供的方法则是静态的。更有意思的是,java中虽然没有静态构造函数的概念,c#中却是有的。
现在来看看问题三。这样的设计的优点在于能够控制对象的创建个数,缺点在于无法实法面向对象的重要概念:继承。基于解决这个问题有很多大神提出了用protected来替代private的写法。下面是protected的代码
public class ClassA
{
protected ClassA()
{
}
}
public class ClassB extends ClassA
{
public ClassB()
{
}
}
总结
突然有一种感觉,设计模式的结构看似简单,其中细节之处却蕴含了很深的道理,值得我们去深思。