单例模式

单例模式是最基础的模式,记得上学的时候,老师介绍的也就是单例,工厂的简单应用。

今天学到了一个新的知识点,往常概念里为了保证是单例,必须要构造函数设置为private,这样才能保证在其他地方不被实例化出对象。可是private的类不能被继承,这点从来没考虑到。

举3个例子看看代码,基本就能明白基础的单例模式的意义。

public class Singleton {
//在自己内部定义自己一个实例
//注意这是private 只供内部调用
private static Singleton instance = new Singleton();
//如上面所述,将构造函数设置为私有
private Singleton(){
}
//静态工厂方法,提供了一个供外部访问得到对象的静态方法
public static Singleton getInstance() {
return instance;
}
}
下面这种方式被称为懒汉式:P
public class Singleton {
//和上面有什么不同?
private static Singleton instance = null;
//设置为私有的构造函数
private Singleton(){
}
//静态工厂方法
public static synchronized Singleton getInstance() {
//这个方法比上面有所改进
if (instance==null)
instance=new Singleton();
return instance;
}
}

以上两种实现方式均失去了多态性,不允许被继承。还有另外一种灵活点的实现,将构造函数设置为受保护的,这样允许被继承产生子类。这种方式在具体实现上又有所不同,可以将父类中获得对象的静态方法放到子类中再实现;也可以在父类的静态方法中进行条件判断来决定获得哪一个对象;在GOF 中认为最好的一种方式是维护一张存有对象和对应名称的注册表(可以使用HashMap 来实现)。下面的实现参考《java 与模式》采用带有注册表的方式

public class Singleton
{
//用来存放对应关系
private static HashMap sinRegistry = new HashMap();
static private Singleton s = new Singleton();
//受保护的构造函数
protected Singleton()
{}
public static Singleton getInstance(String name)
{
if(name == null)
name = "Singleton";
if(sinRegistry.get(name)==null)
{
try{
sinRegistry.put(name , Class.forName(name).newInstance());
}catch(Exception e)
{
e.printStackTrace();
}
}
return (Singleton)(sinRegistry.get(name));
}
public void test()
{
System.out.println("getclasssuccess!");
}
}
public class SingletonChild1 extends Singleton
{
public SingletonChild1(){}
static public SingletonChild1 getInstance()
{
return (SingletonChild1)Singleton.getInstance("SingletonChild1");
}
public void test()
{
System.out.println("getclasssuccess111!");
}
}
原文地址:https://www.cnblogs.com/chenyao/p/3012651.html