【问题标题】:Java Abstract Factories and Singletons [duplicate]Java抽象工厂和单例[重复]
【发布时间】:2014-11-15 23:20:45
【问题描述】:

我想实现一个抽象工厂的例子,但是具体工厂必须作为单例。

这里举Banas先生的例子:http://www.newthinktank.com/2012/09/abstract-factory-design-pattern/我应该修改UFONemyShipFactory和UFOBossEnemyShipFactory吧?

我为 UFOEnemyShipFactory 尝试了一些东西,但我不确定是否正确:

public class UFOEnemyShipFactory implements EnemyShipFactory{

    private UFOEnemyShipFactory(){};

    private static UFOEnemyShipFactory firstInstance = null;

    public static UFOEnemyShipFactory getInstance(){
    
        if(firstInstance == null){
        
            synchronized(UFOEnemyShipFactory.class){
            
                if(firstInstance == null){
                
                    firstInstance = new UFOEnemyShipFactory();
                
                }
            
            }
        
        }
    
        return firstInstance;
    
    }

    public ESWeapon addESGun(){
        return new ESUFOGun();
    }

    public ESEngine addESEingine() {
        return new ESUFOEngine();
    }

这似乎有点奇怪,我认为我没有在正确的类中应用所需的修改。如果我完全错了,请给我一个简短的解释(为什么我错了,我必须修改哪个类以及为什么?)

提前致谢。

【问题讨论】:

  • 如果你真的想要一个单例,为什么不使用enum? Java 语言完成了所有繁重的工作。当然,关于单例是否好存在很多争议。 embeddedrelated.com/showarticle/691.php

标签: java design-patterns singleton factory-pattern


【解决方案1】:

恐怕我没有关于您的 AbstractFactory 问题的完整信息,但我可以帮助您解决单身问题...

通常,当您尝试单例设计模式时,您会指定 private 构造函数,这样其他人就无法使用默认构造函数来创建自己的实例。

作为补充观察,您已经陷入了经典的“双重检查”反模式(不能做的事情)。我在这里写了更多:What's wrong with the following getInstance() method 基本上,不要在同步块之外检查,同步,然后再次检查。看起来它是安全的,但事实并非如此。为此:

public static UFOEnemyShipFactory getInstance(){
    if(firstInstance == null){
        synchronized(UFOEnemyShipFactory.class){
            if(firstInstance == null){
                firstInstance = new UFOEnemyShipFactory();
            }
        }
    }
    return firstInstance;
}

写这个:

public static synchronized UFOEnemyShipFactory getInstance(){
    if(firstInstance == null){
                firstInstance = new UFOEnemyShipFactory();
    }
    return firstInstance;
}

或者很多人会争辩得更好:

private static final UFOEnemyShipFactory firstInstance = new UFOEnemyShipFactory();

public static UFOEnemyShipFactory getInstance(){
    return firstInstance;
}

也是一个风格点。虽然理论上您可以随意命名,但“firstInstance”会提出问题。有“第二个实例”吗?但是,“实例”(至少在 java 意义上)通常意味着“唯一的”。最好只是“实例”。如果您的想法是让 2 个单例在某处闲逛,但它们是不同的,您可以将它们命名为 ufoBossInstanceufoGruntInstance,例如在参考页面的命名之后。

【讨论】:

  • 您的第二次代码发布毫无意义;你可以让它成为一个单一的空检查。仔细检查 null 的原因(至少在理论上)是您可以在同步之前廉价地进行其中一项检查。
  • @Jason S. 是的,谢谢。我的编辑错误...已更正。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-17
  • 1970-01-01
相关资源
最近更新 更多