Проектное решение: создать OrderNumber, который зависит от значения базы данных - PullRequest
0 голосов
/ 25 октября 2011

Я строю систему заказов, используя C #, и у меня возникла проблема при создании номера заказа.

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

Поскольку шаги заказа очень сложны (4 шага, некоторые шаги могут занять 10 минут), поэтому мне нужно сохранитьпорядок на каждом этапе.Но клиент не хочет тратить впустую OrderNumber (номера заказов в формате «Year-Month-An_DB_Value»), потому что последняя часть OrderNumber указывает количество заказов в этом месяце.Таким образом, OrderNumber должен назначаться только тогда, когда пользователь нажимает кнопку «Запрос подтверждения».

Для генерации OrderNumber и поддержания чистоты класса Order (не зависит от базы данных и может тестироваться модулем), я хочу сделать интерфейс IOrderNumberGenerator.в качестве аргумента конструктора класса Order, например:

public class Order {
    public string OrderNumber { get; private set; }

    public Order(IOrderNumberGenerator generator) {
        // ...
    }
}

Но есть проблема:

Заказ может быть сначала сохранен без назначения OrderNumber.Поэтому, если через несколько дней пользователь захочет передать Заказ верификатору заказа, он нажмет кнопку «Запрос подтверждения», и система извлечет объект Заказа из базы данных через O / R Mapper (я использую NHibernate), обратите вниманиечто здесь у нас нет возможности передать IOrderNumberGenerator , поскольку объект Order извлекается из O / R Mapper, ORM воссоздает объект Order, вызывая конструктор по умолчанию класса Order (поэтому у нас нетспособ передать IOrderNumberGenerator).Вот демонстрационный код:

Order order = repository.GetOrder(orderId);

// code to generate the order number

xxx.SubmitChanges();

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

Обновления: Сейчас я думаю создать метод с именем GenerateOrderNumber () в классе заказов и передать IOrderNumberGenerator, например:

public class Order {
   public void GenerateOrderNumber(IOrderNumberGenerator generator) {
       _orderNumber = generate.Generate();
   }
}

Я думаю, что это может решить проблему, но любойлучшие решения?

Кстати: это расширенный вопрос из моего последнего вопроса: Проектное решение: свойство OrderNumber в классе Order - Public или Private?

Спасибо!

1 Ответ

0 голосов
/ 25 октября 2011

Учитывая, что вы хотите сгенерировать OrderNumber из кода, и учитывая вашу заметку: "Таким образом, OrderNumber должен назначаться только тогда, когда пользователь нажимает кнопку" Запрос подтверждения ""

Я бы сказал «Сформировать заказ» при нажатии «Запрос подтверждения», используя OrderNumberGenerator.

Примерно так:

public class OrderNumberGenerator : IOrderNumberGenerator  
{
   public OrderNumberGenerator(Order  order) 
   {
      //generate new order number for order parameter
   }
}

Другими словами, генерировать заказ в момент запроса (только при необходимости) и обратной зависимости типов Order<->IOrderNumberGenerator

EDIT

Кстати, рассмотрим также генерацию OrderNumber на уровне БД, если это возможно в вашем случае, как предложил Yahia, наиболее надежное решение.

Надеюсь, это поможет.

...