java 单例工厂方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/356004/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Singleton Factory method
提问by Chris B.
Is it possible to have a singleton in a factory method? I have many domains using the factory method. How do I work around with this. Please help me with an example.
工厂方法中是否可以有一个单例?我有很多使用工厂方法的域。我该如何解决这个问题。请帮我举个例子。
回答by Chris B.
In this example, I believe you would want to synchronize your getInstance() method to ensure two threads do not simultaneously enter it. Otherwise two threads can end up inside the block where the singleton is instantiated which is very problematic. The only issue with this solution is you pay a premium for the synchronization of the method every time getInstance() is called. Example:
在这个例子中,我相信你会想要同步你的 getInstance() 方法以确保两个线程不会同时进入它。否则两个线程可能会在单例被实例化的块内结束,这是非常有问题的。此解决方案的唯一问题是您每次调用 getInstance() 时都要为方法的同步支付额外费用。例子:
public static synchronized Singleton getInstance()
{
// since whole method is synchronized only 1 thread can
// enter the following block ensuring only one instance
// is ever created. however we pay a synchronization
// penalty every time this method is called.
if(mInstance==null) {
mInstance=new Singleton();
}
return mInstance;
}
Alternatively you could also switch to use eager initialization of the singleton instance rather than lazy initialization if initializing is cheap which guarantees concurrency as well as not paying a synchronized penalty for invoking the getInstance() method. Example:
或者,您也可以切换到使用单例实例的急切初始化而不是延迟初始化,如果初始化很便宜,这保证了并发性,并且不会为调用 getInstance() 方法支付同步惩罚。例子:
// no synchronization penalty, but penalty for eager init
private static Singleton mInstance = new Singleton();
public static Singleton getInstance()
{
return mInstance;
}
The most optimized approach is to use double-checked locking, something you need Java 1.5 or newer to use reliably due to differing implementations of the volatile keyword in 1.4 or older JVMs (please refer to "Head First Design Patterns" chapter 5 p.182 published by O'Reilly Media, Inc. -- that is where I first read about this.) Example:
最优化的方法是使用双重检查锁定,由于 1.4 或更旧的 JVM 中 volatile 关键字的实现不同,您需要 Java 1.5 或更高版本才能可靠地使用它(请参阅“Head First Design Patterns”第 5 章 p.182由 O'Reilly Media, Inc. 出版——这是我第一次读到这个的地方。)示例:
private volatile static Singleton mInstance;
private Singleton(){}
public static Singleton getInstance()
{
if(mInstance==null) {
synchronized (Singleton.class) {
// only pay synchronization penalty once
if(mInstance==null){
mInstance=new Singleton();
}
}
}
return mInstance;
}
回答by mepcotterell
"...create an interface for objects that create instances of the Singleton class. This is essentially a combination of the Abstract Factory, Factory Method and Functor patterns in the GoF book."
“...为创建 Singleton 类实例的对象创建一个接口。这本质上是 GoF 书中抽象工厂、工厂方法和函子模式的组合。”
/**
* An interface defining objects that can create Singleton
* instances.
*/
public interface SingletonFactoryFunctor {
/**
* @return An instance of the Singleton.
*/
public Singleton makeInstance();
}
回答by Bill the Lizard
回答by Markus Lausberg
Singleton you can implement like:
单例你可以实现如下:
public class Singleton {
private static Singleton mInstance;
private Singleton(){}
public static Singleton getInstance()
{
if(mInstance==null){
mInstance=new Singleton();
}
return mInstance;
}
}
This class you can return in every Factory methode you want, like mepcotterell described before.
你可以在你想要的每个工厂方法中返回这个类,就像之前描述的 mepcotterell 一样。
回答by Gabriel Ramirez
This example is not a formal Factory Pattern (GoF) but is still helpful if you use it like a Static Factory Method
这个例子不是正式的工厂模式(GoF),但如果你像静态工厂方法一样使用它仍然很有帮助
abstract class Product {}
class ConcreteProduct extends Product{}
class ProductSupportFactory {
private static ProductSupportFactory instance = null;
private ConcreteProduct product = null;
static {
instance = new ProductSupportFactory();
}
private ProductSupportFactory() {
product = new ConcreteProduct(); //object initialization
}
public static ProductSupportFactory getInstance(){
return instance;
}
public ConcreteProduct getProduct() {
return product;
}
public void setProduct(ConcreteProduct product) {
this.product = product;
}
}
public class ProductConsumer {
public static void main(String args[]){ //client
ConcreteProduct uniqueInstance = ProductSupportFactory.getInstance().getProduct();
ConcreteProduct sharedInstance = ProductSupportFactory.getInstance().getProduct(); //same object hash
}
}

