Ответственность за данные класса - PullRequest
3 голосов
/ 03 октября 2008

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

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

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

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

Спасибо!

Ответы [ 8 ]

4 голосов
/ 03 октября 2008

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

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

1 голос
/ 03 октября 2008

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

0 голосов
/ 03 октября 2008

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

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

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

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

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

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

Начните с поведения
Основной принцип: Упорство - это не поведение. Поведения больше, чем настойчивость.
В вашей системе будет подсистема заказа на покупку. Ваш пользователь сможет взаимодействовать с ним только на высоком уровне (уровень использования). Таким образом, методы будут реализовывать варианты использования заказа на поставку. Эти методы будут использовать DAO через фабрику, если необходимо, для доступа к базе данных и делать все, что им нужно.
Короче говоря, ваш 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...
0 голосов
/ 03 октября 2008

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

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

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

0 голосов
/ 03 октября 2008

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

0 голосов
/ 03 октября 2008

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

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

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

0 голосов
/ 03 октября 2008

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

0 голосов
/ 03 октября 2008

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

...