Обязанности данных классов

У меня есть класс "Order Order". Он содержит информацию об одном заказе на поставку. У меня есть класс DAO для методов базы данных.

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

Если класс PurchaseOrder имеет методы ".update", "insert", "delete" и ".load", которые используют класс DAO напрямую или класс PurchaseOrder не знает методы DAO и имеет класс POController который управляет этими взаимодействиями?

Пользователь будет работать только с одним PurchaseOrder за раз.

Спасибо!

8 ответов

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

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


Я бы сохранил это просто, сделав PurchaseOrder интерфейсом и поместив весь код DAO в реализацию, затем используйте factory.


Это зависит от того, как долго вы думаете, что ваше приложение останется. Приложение для резки металлических изделий компании постоянно развивается с 1985 года и является портом благодаря многочисленным изменениям в компьютерных архитектурах. В нашем случае мы почти всегда заставляем вещи за интерфейсом (или классом контроллера, используя ваши термины), потому что мы не будем тем, что будет состоять из 5, 10, 15 лет.

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

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


Позвольте мне рассказать вам о моих рассуждениях:

Методы класса Основной принцип: Persistance - это поведение класса и должно быть классным методом Вам нужно разобраться в проблемах, поэтому вы помещаете базу данных в класс DAO и используете ее для реализации методов. Первая проблема: если вам нужно поддерживать разные наборы DAO, вам необходимо создать их с помощью Factory. Вторая проблема: не все поведения настойчивости специфически связаны с экземпляром класса. Например, методы List и Search: они возвращают списки классов, а не классы, и не зависят от экземпляра. Таким образом, они являются принципиально статическими методами. Третья проблема: вы хотите поддерживать наследование этого класса. Таким образом, детали сохранения отличаются от родительского к ребенку. Если у вас есть статические методы, это будет проблемой.

Итак, вы переходите к

контроллер Основной принцип: методы сохранения не относятся к одному классу, они больше и, следовательно, они должны быть разделены Необходимо снова устранить проблемы, поэтому вам нужны DAO. Это класс Utility, поэтому методы в основном статичны. Первая проблема: вам понадобится Factory для создания DAO, если вы хотите поддерживать более одного метода сохранения. Вторая проблема: вы хотите поддерживать иерархию классов, поэтому вы не можете использовать статический класс. Вам необходимо сгенерировать контроллеры через Factory. Третья проблема: вы предлагаете своим разработчикам сложный API. Пример кода клиента:

PurchaseOrder po;
PurchaseOrderController poc;
poc = PurchaseOrderControllerFactory.Instance.Create();
po = poc.GetPurchaseOrder(42);
// do stuff
poc.SavePurchaseOrder(po);

тогда я начну с нуля.

Начать с поведений Основной принцип: Настойчивость - это не поведение. Поведение больше, чем настойчивость. В вашей системе будет подсистема заказа на поставку. Ваш пользователь сможет взаимодействовать с ним только на высоком уровне (уровень использования). Таким образом, методы реализуют варианты использования заказа на поставку. Эти методы будут использовать DAO через Factory, если необходимо, для доступа к базе данных и делать все, что им нужно. Короче говоря, ваш PurchaseOrder - это в основном DTO, быстрый способ передачи данных. Он не должен иметь поведения. Пример кода клиента:

// It could be a factory if needed.
PurchaseOrderSystem pos = new PurchaseOrderSystem(); 
List<purchaseorder> transacted;
transacted = pos.TransactPurchaseOrders(john, 23);
// Show transacted purchase orders or whatever...
</purchaseorder>


Класс PurchaseOrder должен быть не осведомлен о DAO. Класс purchaseOrder должен представлять сами данные и не более того. Используйте диспетчер или диспетчер служб или все, что вы хотите назвать, чтобы сохранить/загрузить записи PurchaseOrder с помощью DAO. Это дает вам максимальную гибкость в вашем дизайне. У вас есть одно место для вашей модели данных, одно место для вашей бизнес-логики (контроллер) о том, как хранятся/извлекаются PurchaseOrders, и одно место, где оно фактически сохранялось.


Ключевым моментом, о котором стоит подумать, является то, что вы, возможно, захотите сделать в будущем. Может быть, вы хотите заменить свою базу данных на другую? Вот почему вы обязательно должны отделять свой код от взаимодействия с базой данных из класса, представляющего PO. Это основное разделение ответственности, и я надеюсь, что вы уже это сделали.

Теперь возникает вопрос: хотите ли вы, чтобы третий класс (контроллер) управлял взаимодействием между классами PO и DAO? Я думаю, это зависит от того, насколько вы можете сделать интерфейс для класса DAO. Если интерфейс DAO является достаточно общим, чтобы вы могли записать замену плагина с помощью другого механизма хранения, но без изменения интерфейса, я бы позволил классу PO взаимодействовать с ним. Если нет, я бы написал класс контроллера.

Другая вещь, о которой нужно подумать, - это остальная часть структуры. Откуда начинается сохранение/загрузка? Если вы собираетесь делать много манипуляций с ПО (сохранять, загружать, печатать, отправлять по клиенту), то, вероятно, имеет смысл иметь контроллер, который выполняет все эти функции, а не интегрирует функциональность в класс PO, Это дает вам преимущество в том, что вы можете добавлять операции PO без изменения класса PO.


Лично я создам объект, который управляет взаимодействиями. Я не могу сделать убедительный аргумент в пользу того, что НЕ вставлять эту логику в класс PurchaseOrder, но создание этого объекта контроллера приведет к более слабосвязанным объектам.


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

licensed under cc by-sa 3.0 with attribution.