На первом этапе разработки я проектирую Car
а также AI
как 1 лицо.
Хорошо работает (псевдокод): —
for(every entity that is "racing car"){
//^ know type by using flag
// or iterate special component (e.g. "RacingCarComponent")
Entity entity=...
AI* ai=get<AI>(entity);
ai->setInformation(...)
}
for(every entity that is "bicycle"){
Entity entity=...
AI* ai=get<AI>(entity);
ai->setInformation(...) //the info is very different from "racing car"}
Позже я хочу новую функцию: включить драйвер In-Out (который влияет на AI).
Я разделил сущность, как показано на следующей диаграмме:
Код выше будет обновлен, чтобы быть: —
for(every entity that is "racing car"){
Entity entity=...
AttachAI* aiAttach=get<AttachAI>(entity); //<-- edit
aiAttach->ai->setInformation(...) //<-- edit
}
for(every entity that is "bicycle"){
Entity entity=...
AttachAI* aiAttach=get<AttachAI>(entity); //<-- edit
aiAttach->ai->setInformation(...) //<-- edit
}
Он хорошо работает как до, так и после изменения, но его трудно поддерживать.
Если есть N
типы транспортных средств в version1 например truck, motercycle, plane, boat, rocket
,
Мне придется редактировать N*2
линии которых потенциально уже разбросаны по многим .cpp
,
Главная проблема : Если я забуду выполнить рефакторинг любого кода, он все равно будет хорошо скомпилирован.
Проблема появится только во время выполнения.
В реальной жизни я сталкиваюсь с такой проблемой всякий раз, когда новый дизайн желает разделить сущность на множество более простых сущностей.
Рефакторинг всегда просто добавляет еще одно косвенное направление.
Предположим, что в version1, Я не ожидаю, что я захочу включить / выключить драйвер.
Можно ли предотвратить проблему? Как?
Я могу ошибаться, но кажется, что вы, возможно, просматриваете все объекты несколько раз, проверяя условие. Я не совсем уверен в синтаксисе c ++, поэтому, пожалуйста, потерпите меня:
for (entities as entity) {
info = null;
//Check type to get specific info
if (type is a "racing car"){
info = "fast car";
}
elseif (type is a "bicycle") {
info = "rad spokes";
}
//If we found info, we know we had a valid type
if (info isnt null) {
aiAttach = get(entity);
aiAttach->ai->setInformation(info);
}
}
Я не уверен, что функция get требует чего-то определенного для каждого типа. В моем примере с псевдокодом я предполагаю, что мы отправляем только сущность, а не что-то конкретное для конкретного типа. Если это так, можно использовать дополнительную переменную.
Других решений пока нет …