Циклическая зависимость между 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, либо простое внедрение в конструктор, в зависимости от ваших потребностей.

Другие вопросы по тегам