Извлечено из замороженного
20-explanation/simulation. Запись существует потому, что решение выглядит нарушением нашего же правила и его тянет «почистить».
Решили: ICombatContext живёт как интерфейс, хотя реализация у него одна —
CombatSimulation. Это осознанное исключение из правила code-standards §4 («IFoo→Foo
один-к-одному без второй реализации или границы теста не заводить»).
Почему: компоненты эффектов лежат в Combat и обязаны мочь влиять на мир — но не должны знать
про конкретный класс CombatSimulation и тем более мутировать его поля. Контекст — это узкий
контракт влияния: он перечисляет, что эффекту вообще разрешено сделать с боем, и тем самым ограничивает
его, а не открывает доступ. Второе основание — тест: узкий интерфейс мокается, а CombatSimulation
целиком нет.
То есть правило не нарушено, а сработало по второму условию: интерфейс здесь — граница, просто граница не для подмены реализации, а для ограничения прав. Убрать его «раз реализация одна» значит открыть каждому компоненту эффекта весь класс симуляции.
Грабли: шов протекает. Часть воздействий (статы и ресурс) ходит мимо ICombatContext напрямую,
и это известный хвост — пока контракт не полон, ограничение держится дисциплиной, а не типом. Отдельный
заход; не считать существующие протечки разрешением добавлять новые.
Владелец правды: Assets/_Project/Scripts/Combat/ICombatContext.cs и его реализация в
CombatSimulation; правило про интерфейсы — Reference - Code Standards §4.