ООП ДАО дизайн вопрос - PullRequest
       15

ООП ДАО дизайн вопрос

0 голосов
/ 10 сентября 2009

Краткая справка: я программирую на PHP, у меня есть модель домена с отдельным уровнем доступа к данным (классы DAO), которые отвечают за выборку данных из БД и создание классов домена.

Допустим, у меня есть класс DAO, отвечающий за создание объектов group и groupList . Вы можете представить группы как компонент социальной сети; хотя на самом деле не имеет значения, что они за этот вопрос.

Мне нужно иметь возможность попросить DAO сделать меня различными groupList объектами на основе различных критериев:

  • последние добавленные группы
  • самые популярные группы
  • группы, определенные администратором как "избранные"
  • групп, помеченных определенным тегом
  • групп, соответствующих определенному ключевому слову
  • группы в определенной категории
  • групп, созданных определенным человеком
  • групп, созданных в определенный день

Некоторые из них на самом деле мне сейчас не нужны, но я могу себе представить, что они понадобятся мне до того, как проект будет завершен. Теперь я начал с хорошего простого метода DAO: createList . Это сработало отлично. Вы можете думать о псевдокоде как:

find out how many groups
create SQL query to fetch group details
loop through results
{
   create group object
   add to group list object
}

По мере развития моего приложения я создал новый метод createFeaturedList . Это сработало отлично. Но на самом деле это было очень очень похоже на createList с немного другим запросом. Большая часть остальных ~ 150 строк кода была идентична.

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

a) создать множество целенаправленных творческих методов, таких как:

  • createList ()
  • createCategoryList (categoryObject)
  • createUsersList (userObject)
  • createTagList (tag)
  • createPopularList ()

или

b) создать один БОЛЬШОЙ метод, который может делать все: - createList (searchString, orderBy, filterByCategoryObject = null, filterByUserObject = null)

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

У меня был флирт с рефакторингом в (b), но я вижу, что мой метод становится очень большим и очень сложным, довольно быстрым, много "если" и "выбирают", чтобы иметь дело с различными случаями при построении SQL и множество параметров, которые вводятся в метод. Но, по крайней мере, все это в одном месте. И вы можете комбинировать вещи; Например: группы пользователей, помеченные бла, соответствующие ключевые слова бла.

Ответы [ 5 ]

1 голос
/ 10 сентября 2009

Метод big в варианте B почти гарантированно уменьшит повторное использование кода, а также увеличит сложность и время обслуживания.

Лично (и в соответствии с Code Complete) методы должны делать одну вещь и делать это хорошо, а не пытаться втиснуть все. Избегать необходимости рефакторинга в будущем и делать это с умом в первый раз.

1 голос
/ 10 сентября 2009

Я не думаю, что это строго ситуация или ситуация. Опция a - это удобный интерфейс для вашего DAO, поэтому я думаю, что вы должны сохранить это. Для меня вариант b действительно похож на конкретную логику реализации. Так что, если БОЛЬШОЙ метод соответствует вашим целям, я бы сказал, чтобы использовать его для выполнения фактической логики обработки, в то же время раскрывая интерфейс, как в опции a.

Тем не менее, если BIG-метод становится слишком сложным и сложным, а повторное использование кода фактически увеличивает сложность вашего кода и снижает удобство сопровождения приложения, тогда вы можете захотеть реорганизовать рефакторинг, чтобы сохранить отдельные операторы SQL для каждого метода интерфейса, но иметь вспомогательный метод для выполнения. общая логика разбора результатов.

1 голос
/ 10 сентября 2009

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

private function _createList ( searchString, orderBy, ... )
{
    ...
}

public function createList()
{
    return $this->_createList('...', 'id');
}

public function createCategoryList()
{
    return $this->_createList('...', 'category_id');
}

Таким образом, если ваша функция _createList должна быть изменена позже, вам нужно только реорганизовать открытые методы в этом DAO, а не все классы, которые используют этот DAO.

0 голосов
/ 10 сентября 2009

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

for(group in group) {
    cont = true
    for(f in functions) {
        if ! f(group) {cont = false; continue;}
    }
    if(cont) Continue
    add group to list
}

Это позволит вам изменять параметры фильтрации, не изменяя цикл, просто записывая или изменяя функцию.

0 голосов
/ 10 сентября 2009

Основы программирования: хорошая практика разбивать ваши коды на разделы или функции.

Я пойду на вариант (а); Вам нужно будет поддерживать и отлаживать код. И когда у вас есть ошибка, вы будете очень рады, что вы разбили свой код на различные методы.

Кроме того, написание имени метода поможет вам понять, что вы делаете.

Сравните это:

Вариант (а)

$obj->AddNewList( /* params */ );
$obj->UpdateList( /* params */ );

и это:

Опция (б)

$obj->parse( /* first set of params */ );
$obj->parse( /* second set of params */ );

Это экономит время, когда люди читают слева направо. Вот почему имена функций и методов всегда находятся слева.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...