Проектное решение: свойство OrderNumber в классе Order - Public или Private? - PullRequest
0 голосов
/ 25 октября 2011

Я строю систему заказов. И здесь у меня есть класс Order, у которого есть свойство с именем OrderNumber. Как вы знаете, OrderNumber может быть назначен только один раз, поэтому я не хочу делать это public (поэтому я сделал это private).

Однако номер заказа генерируется в соответствии с порядковым значением, хранящимся в базе данных. Например, значение в базе данных равно 10, теперь я генерирую номер заказа, номер заказа будет "Year-Month-10", а значение будет увеличиваться до 11. Значение будет сбрасываться каждый месяц.

Видите ли, генерация номера заказа зависит от базы данных . Если я сделаю OrderNumber private, я смогу вызвать только метод генерации порядкового номера в классе Order (возможно, в конструкторе), это не очень хорошо и сложно проводить модульное тестирование. И я не хочу использовать ServiceLocator в классе Order, я думаю, что это тоже плохо .

Если я сделаю номер заказа public, вышеуказанные проблемы могут быть решены. Но номер заказа может быть изменен по ошибке некоторых кодировщиков, это небезопасно .

Итак, можно ли сделать свойство OrderNumber публичным? А твои причины?

Обновление:

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

Но есть еще одна проблема: В моем senario номер заказа не назначается при создании объекта Order. Заказчик может создать и сохранить заказ, не передавая его верификатору заказа. Таким образом, перед передачей заказа в верификатор заказа номер заказа не присваивается. OrderNumber назначается только тогда, когда клиент нажимает кнопку « Запросить подтверждение заказа », и затем OrderNumber не может быть изменен снова. И рабочий процесс переходит к следующему шагу (Проверка заказа).

Я создал новый вопрос, пожалуйста, посмотрите здесь: Проектное решение: Создать OrderNumber, который зависит от значения базы данных

Кстати : я использую C #

Спасибо!

Ответы [ 2 ]

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

Я бы порекомендовал иметь общедоступное свойство только для чтения OrderNumber (т.е. сделать set частным) на основе частного поля ... это дает вам преимущества обоих без каких-либо негативных аспектов.

Что-то, что выследует учитывать:

Случаи, подобные тем, которые вы описываете, обычно решаются путем реализации шаблона Factory ...

EDIT - относительно обновления OP:

Создайте класс OrderNumber и поместите его как общедоступное свойство в свой класс Order.OrderNumber class имеет только закрытый конструктор и создается только с помощью шаблона Factory.

Таким образом, ваш Order изначально null назначил свойству OrderNumber ... это свойство имеет метод private setкоторый позволяет присваивать только тогда, когда внутреннее поле равно null ... для присваивания OrderNumber, например, у вас есть свойство Status, которое при изменении на Order Verification вызывает сохраненную ссылку на IOrderNumberGenerator (из конструктора)и установите OrderNumber один раз ...

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

Помните, что вы можете установить видимость методов получения / установки свойства:

public class Order
{
    private string orderNumber_;

    public string OrderNumber
    {
        get { return orderNumber_; }
        private set { orderNumber_ = value; }
    }
}

Обновление

Учитывая ваше требование, почему бы не реализоватьвторой конструктор, который берет генератор номера заказа и существующий заказ?

public interface IOrderNumberGenerator
{
    string Generate();
}

public class Order
{
    private string orderNumber_;

    // default ctor
    public Order()
    {
    }   // eo ORder

    public Order(IOrderNumberGenerator generator, Order order)
    {
        orderNumber_ = generator.Generate();
        /* copy other fields from the existing Order*/
    }

    public string OrderNumber
    {
        get { return orderNumber_; }
    }
}   // eo class Order
...