Циклическая зависимость между Datas-проектом и Builders-проектом
Вот код, который я хочу достичь:
Character
имеетstrength
,constitution
и некоторые другие характеристики.- каждый
Character
имеетBaseStats
в зависимости от его класса.- каждый
Character
имеетRandomStats
бонус, с положительными значениями от 0 до 3.- Стат не может быть ниже 1 или выше 10.
Character
можно иметьBonus
а такжеMalus
в их статистике.- Если
Character
имеет 8 вstrength
плюс бонус 4 и малый 1, у него наконец 10 (8+4-1=11 > 10).- Если
Character
имеет 3 по конституции, плюс бонус 1 и малус 4, у него наконец 1 (3+1-4=0 < 1).
В моем решении.NET я пытаюсь отделить datas
а также builders
в разных проектах. В настоящее время у меня есть что-то подобное в моем datas
проект:
namespace Data.Entities.Characters
{
public abstract class Character : Entity
{
public abstract EntityStats BaseStats { get; }
public EntityStats RandomStats { get; }
}
}
namespace Data.Stats
{
public struct EntityStats
{
private Dictionary<EntityStat, int> _stats;
public int this[EntityStat stat] { get { return _stats[stat]; } }
public EntityStats(int strength, int constitution, /* ... */)
{
_stats = new Dictionary<EntityStat, int>();
_stats.Add(EntityStat.Strength, strength);
_stats.Add(EntityStat.Constitution, constitution);
/* ... */
}
}
}
Тогда у меня есть builder
какая сумма List<EntityStats
,
namespace Builder
{
public class EntityStatsBuilder
{
private List<EntityStats> StatsList { get; set; }
public EntityStatsBuilder() { StatsList = new List<EntityStats>(); }
public void Add(EntityStats stats) { StatsList.Add(stats); }
public EntityStats ToStats()
{
int strength = 0,
constitution = 0,
/* ... */;
foreach (EntityStats stats in StatsList)
{
strength += stats[EntityStat.Strength];
constitution += stats[EntityStat.Constitution];
/* ... */
}
// module FMath =
// let Clamp value min max =
// if value < min then min elif value > max then max else value
return new EntityStats(
FMath.Clamp(strength, 1, 10),
FMath.Clamp(constitution, 1, 10),
/* ... */
);
}
}
}
Моя проблема заключается в следующем:
мой
builders
проект ссылается на мойdatas
проект.
ОШИБКА: я хочу добавитьFinalStats
собственность в моемCharacter
учебный класс. этоFinalStats
должен использовать мойEntityStatsBuilder
учебный класс. Тогда мойdatas
проект должен ссылаться на мойbuilders
проект.
public EntityStats FinalStats
{
get
{
EntityStatsBuilder builder = new EntityStatsBuilder();
builder.Add(BaseStats);
builder.Add(RandomStats);
return builder.ToStats();
}
}
Как мне изменить мою глобальную архитектуру, чтобы не было этой циклической зависимости?
1 ответ
То, что вы ищете, называется принципом инверсии зависимостей https://en.wikipedia.org/wiki/Dependency_inversion_principle
В основном создайте интерфейс для вашего EntityStatsBuilder
и поместить это в отдельный проект. Теперь оба проекта могут ссылаться на этот интерфейсный проект. Если вы хотите следовать соглашению об именах Microsoft, называйте его SomethingSomething.Abstractions
,
Теперь в вашем стартапе, использующем внедрение зависимостей, вы вводите конкретный EntityStatsBuilder
в вашем Character
объект. Для этого вы можете использовать либо DI Framework, либо простое внедрение в конструктор, в зависимости от ваших потребностей.