Я не думаю, что ваша концепция матрицы будет хорошим способом для достижения вашей цели.Вы получите огромную матрицу, которая содержит все возможности.Очевидно, что извлечение информации, которую вы хотите из матрицы, будет довольно легким, но поддержание ее в долгосрочной перспективе может оказаться болезненным, так как добавляется больше CellObject
подклассов.То же самое относится к n + 1 методам, предложенным вашим коллегой.
В обоих случаях каждый раз, когда вы добавляете подкласс CellObject
, вам придется либо перейти в класс, который содержит матрицу, создатьновая строка и новый столбец для каждой существующей строки, и вручную укажите, может ли этот новый класс быть сложен или нет в классе x, или добавьте новый метод canStackOnNewClassX ()
к каждому существующему классу.На мой взгляд, оба решения подвержены ошибкам (вы можете легко забыть обновить матрицу или ввести неверную информацию, так как код может быть трудно читаемым), есть более элегантные способы решения таких проблем.
Одна вещь, которую вы могли бы сделать, это иметь карту в вашем CellObject
суперклассе, которая будет хранить вашу информацию о «наращиваемости», и предоставлять методы для заполнения этой карты и получения возможности размещения члена класса A на членекласс B. Примерно так:
public abstract class CellObject
{
private static Map<Class<? extends CellObject>, Map<Class<? extends CellObject>, Boolean>> fullStackabilityMap =
new HashMap<Class<? extends CellObject>, Map<Class<? extends CellObject>, Boolean>> ();
protected static void addStackableOnObjectInformation (Class<? extends CellObject> baseObjectClass, Class<? extends CellObject> objectToStack, boolean canStackOnObject)
{
Map<Class<? extends CellObject>, Boolean> stackableMapForObject = fullStackabilityMap.get (baseObjectClass);
if (stackableMapForObject == null)
{
stackableMapForObject = new HashMap<Class<? extends CellObject>, Boolean> ();
fullStackabilityMap.put (baseObjectClass, stackableMapForObject);
}
stackableMapForObject.put (objectToStack, canStackOnObject);
}
protected boolean isStackableOnObject (CellObject baseObject)
{
Map<Class<? extends CellObject>, Boolean> stackableMapForObject = CellObject.fullStackabilityMap.get (baseObject.getClass ());
if (stackableMapForObject == null)
{
return false;
}
Boolean canStackOnObject = stackableMapForObject.get (this.getClass ());
return canStackOnObject != null ? canStackOnObject : false; //Assume that the object cannot be stacked if it was not specified
}
}
public class CellObjectA extends CellObject
{
}
public class CellObjectB extends CellObject
{
static
{
addStackableOnObjectInformation (CellObjectB.class, CellObjectA.class, true);
}
}
public class CellObjectC extends CellObject
{
static
{
addStackableOnObjectInformation (CellObjectC.class, CellObjectA.class, true);
addStackableOnObjectInformation (CellObjectC.class, CellObjectB.class, true);
}
}
Создание fullStackabilityMap
в CellObject
кажется сложным из-за отсутствия в Java оператора Diamond в Java 6, но его можно упростить, если вы напишите утилитуметод, который создает карты, или использовать Гуава.
Таким образом, в этом примере экземпляры CellObjectC
не могут быть наращиваемыми по видам объектов;CellObjectB
экземпляры могут быть сложены только на CellObjectC
объектах, а CellObjectA
могут быть сложены на CellObjectB
или CellObjectC
объектах.
Единственная работа, которую вам придется выполнять при каждом добавленииновый класс должен обновить статические инициализаторы ваших существующих классов, чтобы убедиться, что этот новый класс учтен.Преимущества этого решения:
- Вам нужно только указать, какой тип объекта может быть уложен на какой тип объекта.Нет необходимости полностью инициализировать матрицу со всеми возможностями.
- Вы можете напрямую спросить объект, может ли он быть сложен на объекте любого типа, вместо того, чтобы выполнять статический опрос внешнего класса, что для меня прощеподдерживать и генерировать более чистый код.
- Вам не нужно обслуживать n + 1 методов, которые сообщают вам, что объект A может быть сложен на объекте B, что будет полным кошмаром, если вы в итоге получите значительныйколичество
CellObject
подклассов.