在 Java 中结合工厂模式实现单例模式的最佳方式是什么?详细说明

What is the best way to implement Singleton pattern combined with Factory pattern in Java? Detail in description

我正在学习 JAVA 的设计模式。我想将工厂模式与单例一起使用。现在我不确定我是否采用了正确的方法。

让我先分享一下我尝试过的东西。 我以 Button 为例 class。目的是获取 Button 的 singleInstance,然后获取它的颜色。谁能告诉我它是否可用于实际实施?我是否缺少任何东西或更好的方法?

这是我的代码:

Button.java

public abstract class Button {
    abstract void getButton();
}

ButtonClientClass.java

public class ButtonClientClass {
public static void main(String[] args){
    Button red = ButtonFactory.getButton("RedButton");
    red.getButton();
    System.out.println("hashcode"+red.hashCode());
    Button red2 = ButtonFactory.getButton("RedButton");
    System.out.println("hashcode"+red2.hashCode());

    Button green = ButtonFactory.getButton("GreenButton");
    green.getButton();
    System.out.println("hashcode"+green.hashCode());
    Button green2= ButtonFactory.getButton("GreenButton");
    System.out.println("hashcode"+green2.hashCode());
}
}

ButtonFactory.java

public class ButtonFactory {
public static Button getButton(String button){
    if(button.equals("RedButton")){
        return RedButton.getSingleRedButton();      
    }else{
        return GreenButton.getSingleGreenButton();
    }
}
}

GreenButton.java

public class GreenButton extends Button{

    private static class GreenButtonHolder {
        public static GreenButton INSTANCE = new GreenButton();
    }
    private GreenButton(){}
    public static GreenButton getSingleGreenButton(){
        return GreenButtonHolder.INSTANCE;
    }
    @Override
    void getButton() {
    System.out.println("You have a GreenButton");   
    }
}

RedButton.java

public class RedButton extends Button{
    private static class RedButtonHolder{
        public static RedButton INSTANCE = new RedButton();
    }
    private RedButton(){ }
    public static RedButton getSingleRedButton(){
        return RedButtonHolder.INSTANCE;
    }
    @Override
    void getButton() {
        System.out.println("You have a RedButton"); 
    }
}

枚举是单例,所以:

public enum Button {
    RedButton() {
        public void doSomething() {
            // whatever
        }
    },
    GreenButton() {
        public void doSomething() {
            // whatever else
        }
    };
    public void getButton() {
        System.out.println("You have a " + name());
    }
    public abstract void doSomething();
}

枚举也可以有字段,在大多数情况下就像一个普通的 class。它们的主要限制是不能扩展 classes,但可以实现接口。

使用enum是实现单例最简单的方法。 JVM 将确保实例是唯一的,而无需任何必要的努力。这就是为什么它也是更安全的方式。 您的示例可能如下所示:

Button.java

public interface Button {
    void printButton();
}

GreenButton.java

public enum GreenButton implements Button {
    INSTANCE;

    @Override
    public void printButton() {
        System.out.println("Green button");
    }
}

RedButton.java

public enum RedButton implements Button {
    INSTANCE;

    @Override
    public void getButton() {
        System.out.println("Red button");
    }
}

ButtonFactory.java

public ButtonFactory {

    /*
    * In such situation, where you select one from few states (like you do for colors)
    * it's also better to use enum instead of String. It's more convenient to reuse your code. 
    */
    public static Button getButton(ButtonType type) {
        if (type == ButtonType.GREEN)
            return GreenButton.INSTANCE;
        if (type == ButtonType.RED)
            return RedButton.INSTANCE;
    }

    public static enum ButtonType {
        GREEN, RED;
    }
}