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



我目前正在实现一个游戏,其中有不同类型的地图。由于都是映射,它们自然共享某些属性和方法,因此创建了一个抽象类Map,然后由SafeMapHazardousMapWeirdMap等映射进行子类化。

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

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 实例(无论选择哪个子类)。我读过,最好的方法是部署单例设计模式,其中静态实例在类中私有声明,构造函数也私有。但我不知道如何结合工厂方法设计模式来完成此操作,因为我们有多个子类,getInstance()必须在具体的类中。

我感谢任何帮助。


注意:我看过一些类似的问题,但我认为对这些问题的回答与我的情况无关。

最简单的方法是使用单个静态字段,如果已创建映射,则返回该值。

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

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;
}
}

服务定位器模式就是您正在寻找的。

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

它由一个 Map 组成,该 Map 将接口类作为键,将对象作为值(它可以容纳许多单例类/接口)。

因此,您可以拥有一个带有哈希映射的服务定位器,其中包含一个以 Map.class 作为键并将所需实例作为值的条目。

您将通过以下方式获取该值(例如):

ServiceLocator.get(Map.class);

其中get是一个通用的getter,它包装了你的HashMap.get(Map.class);

最新更新