Java抽象工厂和单例
我想实现一个抽象工厂的例子,但是具体工厂必须作为单例 以巴纳斯先生为例:我应该修改UFOEnemyShipFactory和UFOBossEnemyShipFactory,对吗 我为UFOEnemyShipFactory尝试了一些东西,但我不确定是否正确:Java抽象工厂和单例,java,design-patterns,singleton,factory-pattern,Java,Design Patterns,Singleton,Factory Pattern,我想实现一个抽象工厂的例子,但是具体工厂必须作为单例 以巴纳斯先生为例:我应该修改UFOEnemyShipFactory和UFOBossEnemyShipFactory,对吗 我为UFOEnemyShipFactory尝试了一些东西,但我不确定是否正确: public class UFOEnemyShipFactory implements EnemyShipFactory{ private UFOEnemyShipFactory(){}; private static UF
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();
}
这似乎有点奇怪,我认为我没有在正确的类中应用所需的修改。如果我完全错了,你能给我一个简单的解释吗(为什么我错了,我必须修改哪个类,为什么?)
提前谢谢。恐怕我没有关于AbstractFactory问题的完整信息,但我可以帮助您解决单例问题 通常,当您尝试单例设计模式时,您会指定一个私有构造函数,这样其他人就不能使用默认构造函数来创建自己的实例 作为一个补充观察,您已经进入了经典的“双重检查”反模式(一些不应该做的事情)。我在这里写了更多: 基本上,不要在同步块之外进行检查,先进行同步,然后再次检查。看起来很安全,但事实并非如此。为此:
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;
}
也是一个风格点。从理论上讲,你可以随心所欲地说出事情的名称,“第一个实例”会引发问题。是否有“第二个实例”?但是,“实例”(至少在java意义上)通常意味着“唯一”。最好只是“举例”。如果您的想法是在某个地方有两个单例,但它们是不同的,您可以将它们命名为
ufoBossInstance
和ufoGruntInstance
,例如在引用页面的命名之后。如果您确实想要单例,为什么不使用enum
?Java语言完成了所有繁重的工作。当然,对于单身汉是否好有很多争议。你的第二个代码帖子毫无意义;您可以只进行一次空检查。重复检查null(至少在理论上)的原因是,您可以在同步之前廉价地执行其中一项检查。@Jason S.是的,谢谢。我的编辑错误…已更正。