结合工厂方法和单例设计模式

Combining the Factory Method and Singleton Design Patterns

我目前正在开发一款包含不同类型地图的游戏。作为所有映射,它们自然共享某些属性和方法,因此创建了抽象 class Map,然后由 SafeMap、[=] 等映射子class 13=]、WeirdMap、等等

为了方便以后添加更多地图,使用了工厂方法设计模式。所以该程序包含一个 MapCreator class 其代码如下所示:

public class MapCreator{
    public Map createMap(char mapType){
        switch(mapType){
            case 'S':
                return new SafeMap();
            case 'H':
                return new HazardousMap();
            case 'W':
                return new WeirdMap();
            default:
                return null;
        }
    }
}

现在我还想强制只存在一个 Map 实例(不管选择的子class)。我读过,解决这个问题的最佳方法是部署单例设计模式,其中静态实例在 class 中私有声明,并且构造函数也设为私有。但是我不知道如何结合工厂方法设计模式来做到这一点,因为我们有多个 subclasses 并且 getInstance() 必须在具体的 class.[= 中18=]

感谢任何帮助。


注意:我看过 a few similar questions,但我认为对这些的回复与我的情况无关。

最简单的方法是使用单个静态字段,return如果地图已经创建,则使用该值。

代码未经测试,但我认为这个概念很简单:

public class MapCreator{
    private static Map theOnlyMap;
    public synchronized Map createMap(char mapType){
        if( theOnlyMap != null ) return theOnlyMap;
        switch(mapType){
            case 'S':
                theOnlyMap = new SafeMap();
                 break;
            case 'H':
                theOnlyMap =  new HazardousMap();
                break;
            case 'W':
                theOnlyMap = new WeirdMap();
                break;
        }
        return theOnlyMap;
    }
}

ServiceLocator 模式正是您要找的。

一般来说,为了避免必须在任何地方使用单例,您倾向于使用这种模式,然后可以在必要时模拟单元测试。

由一个以接口class为键,以对象为值的Map组成(可以容纳多个Singletonclasses/interfaces)。

因此,您可以拥有一个带有哈希映射的 ServiceLocator,该哈希映射具有一个以 Map.class 作为键并以所需实例作为值的条目。

您将通过(例如)获得值:

ServiceLocator.get(Map.class);

其中 get 是一个泛型 getter,它包装了 yourHashMap.get(Map.class);