我目前正在实现一个游戏,其中有不同类型的地图。由于都是映射,它们自然共享某些属性和方法,因此创建了一个抽象类Map
,然后由SafeMap
、HazardousMap
、WeirdMap
等映射进行子类化。
为了便于将来添加更多地图,使用了工厂方法设计模式。因此,该程序包含一个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);