Как спроектировать систему вокруг состояния объекта, чтобы не дублировать механизмы в коде и бэкэнде?

1

Система, с которой я работаю с банкоматом, - это С# и оракул, однако проблема, с которой я столкнулась, - это системная агностика (может случиться с системой с java и mysql или с любой другой интерфейсной и обратной связью):

У меня есть объект TransactionDetail который может иметь 9 статусов

Open, 
Complete, 
Cancelled,
No Quote, 
Quoted, 
Instructed, 
Declined, 
Refunded, 
Removed

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

Таким образом, статусы извлекаются с помощью таких механизмов (это всего лишь фрагмент кода, но должен дать вам указание, как он работает)

public TransactionStatus TransactionStatus()
{
    if (db.DeclinedTransactions.Any(o => o.TransactionId == this.TransactionId))
        return TransactionStatus.Declined;
}

MI запрашивает эти статусы транзакций в представлении SQL, которые также будут содержать все данные, относящиеся к транзакции.

Если статус объекта можно определить только из данных самого объекта, то создаваемые столбцы могут решить эту проблему в базе данных. Но как насчет таких объектов, как TransactionDetail которые охватывают несколько таблиц - нет расчетного механизма столбцов, который позволит "заглянуть" в другие таблицы.

Единственное решение, о котором я могу думать, это добавить функцию SQL, которая определяет состояние, а затем создать представление SQL, содержащее данные функции + из таблицы. То, что мне не нравится в этом подходе, заключается в том, что для этого требуется дублировать логику в коде и в базе данных.

Как следует проектировать систему вокруг состояния объекта, которое требуется определить, требует информации из более чем одной таблицы, таким образом, чтобы не требовалось дублировать механизмы в коде и в исходном тексте?

Теги:
architecture
state

1 ответ

1
Лучший ответ

Если бы это был проект, над которым я работал, я бы не хотел создавать View для расчета этих данных.

Я бы посмотрел на мою бизнес-логику приложений.

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

Если у вас есть надежная структура бизнес-логики (т.е. Четко определенные бизнес-объекты, хорошая инкапсуляция, надежные модульные тесты), то я лично хотел бы добавить это к бизнес-объектам.

Затем вы можете определить поведение статуса в коде и обновить явное состояние. Например, если внесение изменений в бизнес-объект, который помещает его в другой TransactionStatus вы можете явно внести изменения в этот статус в бизнес-объект и сохранить все изменения в своей базе данных.

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

Пример:

  • Счет-фактура содержит один или несколько экземпляров InvoiceItem
  • Значение InvoiceItem имеет значение.
  • При выставлении счета-фактуры требуется общая сумма счета-фактуры

Обычным способом, который это делается, является использование SUM() для вычисления суммы счета "на лету" в базе данных для заполнения значения Invoice.Total.

Но если моя бизнес-логика четко определена - возможно, я добавляю InvoiceItem к объекту Invoice в коде, а логика Add также принимает значение из InvoiceItem и добавляет его в значение Invoice.Total - тогда, когда я Invoice.Total изменения, я также могу совершить это Invoice.Total значение.

Когда я хочу отобразить общее количество, у меня есть одно значение, вместо того, чтобы агрегировать в базе данных.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню