Нужна помощь с моделью домена - PullRequest
1 голос
/ 31 марта 2011

Я привык проектировать свои приложения, используя подход, основанный на базе данных, и теперь я хотел бы начать с модели. У меня есть следующие требования, и я хотел бы получить ваше мнение об этом. Это в основном активность с точками, связанными с ней.

Активность с доктором Супер 30

  1. Минимум 4 в месяц
  2. Вычтите очко, если вы не достигли минимума (4)
  3. 1 балл или 2 балла, если вы набираете больше 6 баллов в месяц
  4. 2 балла, когда с местным адвокатом

Активность с 120 Доктором

  1. .5 баллов

Деятельность с Партнерством

  1. 2 балла

Мероприятие с последующей партнерской встречей

  1. 2 балла

Итак, я пытаюсь решить, использую ли я здесь иерархию наследования для каждого типа действия или перечисления вне действия. Итак, отвечает ли каждое мероприятие за подсчет своих баллов (но в некоторых случаях необходимо знать общее количество действий, чтобы принять решение) или у меня есть какой-то компонент-оценщик, который знает всю логику.

Любые идеи были бы великолепны!

Пока у меня есть такой дизайн, но я не знаю, где обращаться с правилами Super 30:

public abstract class ActivityBase {
    public int Id { get; set; }
    public DateTime Date { get; set; }
    public abstract double CalculatePoints();
}

public class SuperThirtyActivity : ActivityBase {
    public bool WithCE { get; set; }
    public bool WithLocalAdvocate { get; set; }

    public override double CalculatePoints() {
        if (Date.Month == 3 && Date.AddDays(7).Month == 4)
            return 1;
        else if (WithCE || WithLocalAdvocate)
            return 2;
        else
            return 1;
    }
}

public class OneTwentyActivity : ActivityBase {
    public override double CalculatePoints() {
        return .5;
    }
}

public class PartnershipActivity : ActivityBase {
    public override double CalculatePoints() {
        return 2;
    }
}

Теперь, чтобы разобраться с правилами Super 30, я подумал о введении следующего класса. Тем не менее, некоторая логика домена просачивается сюда. Это нормально или какие-то другие идеи?

public class Scorer {
    public double CalculateScore(IEnumerable<ActivityBase> activities) {
        var score = activities.Select(a => a.CalculatePoints()).Sum();
        var count = activities.Count(a => a is SuperThirtyActivity);

        if (count < 4)
            score--;
        else if (count > 6)
            score += count;

        return score;
    }
}

Ответы [ 2 ]

1 голос
/ 31 марта 2011

Если базовый класс действия не будет содержать логику, я рекомендую создать интерфейс IActivity и создать 4 класса для его реализации вместо наследования. У IActivity должен быть метод наподобие CalculatePoints, который будет реализован каждым реализующим классом.

Если вы не собираетесь проверять типы действий где-либо в вашем приложении, я имею в виду, что у вас никогда не будет такого кода, как:

if (activity is PartnershipActivity){ 
//do something 
}
else if (activity is FollowUpActivity) {
// do something else
}

и если вы уверены, что в будущем в приложение не будут введены новые типы действий, вы можете рассмотреть возможность создания одного класса Activity с полем enum, как вы сказали, и выполнить все проверки и вычисления, которые вы упомянули в его бизнес-логике.

0 голосов
/ 31 марта 2011

Поскольку некоторые из точек основаны на агрегированных действиях, похоже, что существует другая концепция, которая не отражена в объектной модели, ActivityCollection.Это указывается в параметре Scorer.CalculateScore, но, возможно, это необходимо сделать явным.Затем ActivityCollection может рассчитать баллы, поскольку в нем содержится вся необходимая информация.

С другой стороны, объект Scorer, вероятно, также может выполнять эту роль.Это нормально, что логика домена находится в объекте Scorer, так как это только логика, необходимая для Scorer, чтобы сделать именно то, что подразумевает его имя.Если вы сохраняете Scorer, но переносите в него значения баллов из классов занятий, то эта структура может служить точно так же, если не лучше.

...