Вопрос моделирования данных - разделение данных и расчет и логика доступа - PullRequest
3 голосов
/ 15 января 2009

Хорошо, поэтому я хотел бы получить мнения по этой теме.

У меня тупой объект данных - CustomerOrder.

CustomerOrder имеет цену и количество, но также имеет свойство TotalCash (цена * количество). поэтому у меня есть свойство totalCash, но я не хочу помещать вычисления непосредственно в объект, потому что это нарушит правило тупого объекта данных. Мне нужно получать денежный поток снова и снова по всему приложению, поэтому мне нужно централизовать расчеты. Я мог бы создать класс cashFlowCalculator и передать customerOrder, но мне не нужен другой класс для каждого простого вычисления.

Есть идеи или лучшие практики?

Ответы [ 7 ]

1 голос
/ 15 января 2009

В той же ситуации я бы нарушил «правило тупых объектов данных», так как не ожидаю, что эти конкретные вычисления будут часто меняться. Я, вероятно, реализовал бы это как получатель.

Для более сложных сценариев имеет смысл создать класс OrderCalculator, который принимает классы, связанные с заказами, и может выполнять все виды вычислений, такие как включенный налог, измерение полей и т. Д. Таким образом, вы делегируете обязанности выполнения расчет за пределами CustomerOrder. Таким образом, заказчику не нужно знать о государственном налоге в Техасе, чтобы определить, например, нужен ли налог с продаж.

0 голосов
/ 15 января 2009

Я бы сделал расчет TotalCash в вашем DTO (это был бы YAGNI). Если в будущем вам понадобится изменить поведение TotalCash, то, возможно, посмотрите на создание TotalCashCalculator и передайте его в Орд через DI.

0 голосов
/ 15 января 2009

Я думаю, вам следует подумать, действительно ли вы хотите, чтобы TotalCash был вычисляемым / производным свойством ...

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

Я бы хотел сделать свойство невычисляемым членом DTO и, возможно, также использовать класс обслуживания TotalCostCalculation, используемый для определения заданного значения.

только мои 2 цента.

0 голосов
/ 15 января 2009

другой вариант [возможно, слишком простой для обхода искушенных здесь ;-)] состоял бы в том, чтобы позволить тупому объекту данных иметь свойства для вычисляемых полей, но позволить запросу SQL, который извлекает данные, выполнить вычисление (один раз); сделайте эти поля доступными только для чтения, конечно

0 голосов
/ 15 января 2009

Если это объект передачи данных (DTO), который обновляется из таблицы данных, я бы предложил добавить столбец данных TotalCash в таблицу и установить для свойства столбца данных Выражение значение «цена * количество». Создайте свойство TotalCash только для чтения в немом классе (DTO), которое обновляется из таблицы данных. С точки зрения ОО, так и должно быть.

0 голосов
/ 15 января 2009

Почему бы вам не принять методы расширения?

public sealed class CustomerOrder
{
    public decimal Price;
    public decimal Quantity;
}

public static class CustomerOrderExtensions
{
    public static decimal GetTotalCash(this CustomerOrder data)
    {
        return data.Price*data.Quantity;
    }
}

вы можете даже переместить статические классы вашего расширения в другое пространство имен.

0 голосов
/ 15 января 2009

Я понимаю, что ваши объекты данных должны быть отделены от вашей бизнес-логики. Используя LINQ с классами, сгенерированными дизайнером, я чувствую себя комфортно, расширяя сгенерированный класс частичной реализацией класса, содержащей бизнес-логику. Я чувствую, что этого разделения достаточно для моих нужд. Если это не сработает, то у меня будут и объекты данных, и бизнес-объекты - возможно, с соответствием 1: 1, а может и нет. Фабричный класс или метод могут использоваться для перевода между вашим бизнесом и объектами данных. Затем просто внедрите свою бизнес-логику в свои бизнес-объекты без необходимости во вспомогательных объектах для ваших расчетов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...