我一直在考虑为我的代码实施某种策略。
这是我的设置:
我有一个名为" Object"的界面。 然后我有一个名为" Entity"扩展"对象"。 从实体那里涌现出无数的实现,比如" army"," city"," lemon"等。
现在,我想将所有这些对象收集到某种形式的地图中。然后从该地图我想得到" Object"。
的特定实现我想出的解决办法如下:
对象有方法:
public Entity getEntity()
Object的所有实现都返回null,而Entity返回自身。
同样,在实体I中有:
public Army getArmy()
public City getCity()
这样,我可以简单地从地图中拉出一个对象并通过一系列空检查从中获取特定的类,如此;
Object o = Objects.getObject(2dCoordinates);
Entity e = o.getEntity();
if (e != null){
Army a = e.getArmy();
if (a != null)
a.armySpecificMethod();
}
所有不使用" instanceof"和铸造,我讨厌。
问题是这是否存在一些无法预料的问题?在重构我的代码之前,我宁愿向知道的人学习,也要自己找。
答案 0 :(得分:1)
你问你的策略是否有任何陷阱。我会说不,因为C#使用与as
关键字相同的策略。示例:如果e as Army
是e
,则e
将返回Army
,否则返回null
。它基本上是一个强制转换而不是失败的返回null
。
但是,您不必使用接口实现此功能,您可以编写自己的as
方法,例如:
static <T> T as(Class<T> clazz, Object obj) {
if (clazz.isInstance(obj)) {
return (T) obj;
}
return null;
}
用法:
Object o = Objects.getObject(2dCoordinates);
Entity e = as(Entity.class, o);
if (e != null) {
Army a = as(Army.class, e);
if (a != null)
a.armySpecificMethod();
}
答案 1 :(得分:0)
另一种方法是注册要在特定事件上调用的回调/策略。这样的事情:
public interface OnMapClicked<T> {
void onItemSelected(T item);
}
你的GameMap(或其他)实现将是:
public GameMap {
private final Map<Class<?>, OnMapClicked> listeners = new HashMap<>();
public <T> void registerListener(Class<? extends T> type, OnMapClicked<T> listener) {
listeners.put(type, listener);
}
//
private void onMapClicked(Coordinates coordinates) {
Object object = findObject(coordinates);
listeners.get(object.getClass()).onItemSelected(object);
}
}
这是非常粗略的未经测试的实现,但希望你有了这个想法。这里有一种非泛型实例(在onMapClicked中),但它应该是安全的,因为我们正在检查registerListener
中的输入类型。