[译]Java 设计模式之单例

时间:2022-08-16 05:45:40

(文章翻译自Java Design Pattern: Singleton

单例是在Java最经常被用到的设计模式。它通过阻止其他的实例化和修改来用于控制创建对象的数目。这一特性可应用于那些当只有一个对象存在时能够更加有效的系统,或者是限制对象的实例化数目,比如:

1.私有化构造器(private constructor -)-没有其他的类可以实现化一个新的对象

2.私有化引用(private reference -)-没有其他的修改

3.公共的静态方法(public static method):仅有的获取一个对象的途径

单例的举例

这是一个简单的应用场景。一个国家只会有一个总统。所以任何时候一个总统总是被需要的,唯一的总统应该是返回而不是创建一个新的。getPresident()方法将会确保只有有一个总统被创建。

类图和代码

[译]Java 设计模式之单例

饿汉模式代码:

public class AmericaPresident {
private static final AmericaPresident thePresident = new AmericaPresident(); private AmericaPresident() {} public static AmericaPresident getPresident() {
return thePresident;
}
}

thePresident 被声明为final,所以它只会有一个引用。

懒汉模式:

public class AmericaPresident {
private static AmericaPresident thePresident; private AmericaPresident() {} public static AmericaPresident getPresident() {
if (thePresident == null) {
thePresident = new AmericaPresident();
}
return thePresident;
}
}

单例模式在Java标准库中的应用

java.lang.Runtime#getRuntime() 是Java标准库中最频繁被用到的方法。getRunTime()方法返回了和当前Java应用程序相关的runtime 对象。

class Runtime {
private static Runtime currentRuntime = new Runtime(); public static Runtime getRuntime() {
return currentRuntime;
} private Runtime() {} //...
}

下面是一个实用getRunTime()简单的简单例子,它在一个window系统中读取一个网页。

Process p = Runtime.getRuntime().exec(
"C:/windows/system32/ping.exe programcreek.com");
//get process input stream and put it to buffered reader
BufferedReader input = new BufferedReader(new InputStreamReader(
p.getInputStream())); String line;
while ((line = input.readLine()) != null) {
System.out.println(line);
} input.close();

输出:

Pinging programcreek.com [198.71.49.96] with 32 bytes of data:
Reply from 198.71.49.96: bytes=32 time=53ms TTL=47
Reply from 198.71.49.96: bytes=32 time=53ms TTL=47
Reply from 198.71.49.96: bytes=32 time=52ms TTL=47
Reply from 198.71.49.96: bytes=32 time=53ms TTL=47 Ping statistics for 198.71.49.96:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 52ms, Maximum = 53ms, Average = 52ms

其他的单例模式的实现

由于私有的构造函数并不能阻止通过反射的方式进行实例化对象。Joshua Bloch (Effective Java) 提供了一个关于单例的更好的实现,如果你Mnum 不太熟悉的话,下面就是一个来自于Oracle的不错的例子。

public enum AmericaPresident{
INSTANCE; public static void doSomething(){
//do something
}
}