Основной вопрос об ООП - PullRequest
3 голосов
/ 19 февраля 2010

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

Сначала у меня есть таблица со всеми моими клиентами и их адресами: Код:

Customer
--Id
--Name
--Address
----City
----ZC
----Street

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

1 / Я создаю новый класс:

Код:

CustomerWithBooks
--Id 
--Name
--Books[]
----ID
----name

PRO: загружаю только полезные данные Минусы: я создаю свой класс после моего интерфейса, и есть копирование-вставка.

2 / Я добавляю Книги [] в первый класс. PRO: Все в одном классе, это ремонтопригодно Минусы: я загружаю адрес даром. Если я не загружаю адрес, я могу: ленивая загрузка, но мне действительно это не нравится, или когда я использую свой класс, я должен знать, какой метод моего DAL я вызвал, и мне не нравится. 1019 *

3 / Я использую наследование: Код:

ClientBase
--ID
--Name

ClientWithBooks : ClientBase
--Books[]

ClientWithAdress : ClientBase
--Address

PRO: действительно поддерживается, и я не загружаю данные даром Минусы: что мне делать, если в одном пользовательском интерфейсе я хочу показать книги и адрес?

4 / ?? Я надеюсь, что есть идеальное решение

Ответы [ 5 ]

3 голосов
/ 19 февраля 2010

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

Как "Con" вы говорите: Я строю свой класс после моего интерфейса, и есть копирование-вставка .

  • A. Если вы смоделируете некоторый пользовательский интерфейс, чтобы помочь прояснить требования, прежде чем приступить к разработке и разработке классов, это хорошо , а не плохо.
  • B. Хорошее расположение ваших доменных объектов помогает исключить копирование / вставку, а не вызвать ее. Если в хорошо организованных классах есть какой-то, казалось бы, повторяющийся код (часто это код доступа к данным), это типично, не беспокойтесь. Вы можете обратиться к нему с помощью хорошего слоя / инструмента для доступа к данным, хороших общих ресурсов ведения журналов и т. Д. Повторяющийся код в ваших классах просто означает, что вам нужно улучшить дизайн, , а не , что имеет отдельные классы для всех доменные реалии это плохо.

На странице, где вам нужно иметь дело как с клиентами, так и с книгами, вы будете использовать объекты customer и объекты book и, возможно, объект коллекции books, И в зависимости от того, как настроена ваша db / object-модель, вы можете иметь дело с другими объектами, чтобы получить от покупателя книги, которые они купили. Например, клиенты, вероятно, покупают 1 или более книг одновременно, и они связаны с объектом Order , который имеет ссылку на клиента. Итак, вы, вероятно, перейдете с

  1. Клиент до
  2. Заказы коллекция, содержащая все заказы клиентов для отдельных лиц
  3. Заказ объектов и оттуда к соответствующему
  4. Книги Коллекция, содержащая все
  5. Книга объектов, которые относятся к этому объекту Порядка.

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

1 голос
/ 19 февраля 2010

Я бы хотел избежать 2 и 3, потому что это блокирует вас в ограничительной иерархии, которая на самом деле не соответствует вашим потребностям. Как вы указываете, может быть любая комбинация вещей, которые вы хотите, например, клиенты и их книги, и, возможно, их адрес, и, возможно, их история заказов. Или, может быть, вы захотите книгу со списком клиентов. Поскольку ваша основная бизнес-информация на самом деле не является иерархической, вам следует избегать чрезмерной иерархии объектной модели. В противном случае вы будете встраивать ограничения, которые впоследствии вызовут у вас много головной боли, потому что вы не можете сейчас думать обо всех сценариях.

Я думаю, что вы на правильном пути с 1. Я бы сказал, чтобы создать некоторые базовые классы для Customer и Books, а затем создать класс ассоциации CustomerBook, который содержит экземпляр и клиента, и книги. Тогда вы можете заставить свои методы беспокоиться о том, как загрузить данные в этот список для данного сценария.

0 голосов
/ 19 февраля 2010

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

У вас могут быть высокоэффективные запросы с JOINS, которые возвращают вам клиентов и их книги.

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

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

0 голосов
/ 19 февраля 2010

Вы как бы проектируете задом наперед с точки зрения OOA & D. Нормально использовать управляемый данными дизайн на уровне персистентности (обычно реляционной базы данных). Но в OOA & D более нормально думать о сообщениях, которые объект будет отправлять и получать (вы моделируете методы объекта, а не его члены). Я бы подумал об этом так:

Customer
+getBooks():List<Book>
+getAddress():Address
0 голосов
/ 19 февраля 2010

Я бы вставил адрес в Customer, и у меня была бы отдельная коллекция книг.

Bookshelf
--Books[]

Таким образом, Customer не имеет, но может иметь одну или несколько книг, связанных с ним. Пример PHP-кода следующий:

class BookshelfFactory {
  public static function getBookshelf(Customer $customer) {
     // perform some fetching here
     return $bookshelf;
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...