我一直在重构我的代码,直到我的单元具有以下界面:
public interface IUnit : Entity, IUpdatable
{
byte Team { get; }
bool CanHelp(IUnit unit);
bool CanHurt(IUnit unit);
Position Position { get; }
void CastSpell(ISpell spell, IUnit target);
void GiveSpell(ISpell spell);
void RemoveSpell(ISpell spell);
Duration GetCooldown(ISpell spell);
void SetCooldown(ISpell spell, Duration cooldown);
bool Alive { get; }
float CurrentHealth { get; }
float MaxHealth { get; }
void TakeDamage(HealthChangeEvent @event);
void Heal(HealthChangeEvent @event);
void ApplyStatus(EffectApplicationData data, Aura arua, long duration);
void RemoveStatus(SpellId aura);
bool HasStatus(SpellId aura);
bool CanPay(AbilityCost cost);
bool HasResource(ResourceType type);
float GetResourceValue(ResourceType type);
void GiveResource(ResourceType type, float value);
void SpendResource(AbilityCost cost);
Vector3 GetMovement();
}
最麻烦的部分是
IUnit
用作目标来应用所有ISpell
/IAura
效果,所以每当我想添加一些功能时,我必须向对象添加新功能,这已经太厚了。
我不知道该怎么做,除了使用
IUnit
作为 IAuraOwner
、IHealthOwner
等的容器,并使用带有 IUnit.GetComponent<T>();
的组件系统或直接 getter IUnit.Health
/IUnit.Auras
。
处理这种依赖关系的良好/常见做法是什么?
很难向您推荐最合适的解决方案,因为我无法调查项目的源代码。但您显示的代码违反了接口分离原则,ISP (SOLID)。
要解决此问题,您应该首先定义各个职责并为每个职责创建单独的接口,仅实现与其功能相匹配的接口。
请考虑使用命令、装饰器或策略模式 (GoF)。另外,请查看带有服务层的存储库模式。