Задать вопрос

Стоит ли переписывать полностью метод в данной ситуации?

Есть метод, например: getUsers. Он юзается в 10-20 местах в проекте, и мне вдруг понадобилось получать юзеров отсортированных не по айдишнику (как сейчас), а по колонке order. В голове есть два варианта:
1) Сделать у существующего метода getUsers необязательный параметр (withSorting = false), и в тех самых 10-20 местах оно будет работать как сейчас, потому что там по дефолту проставляется фолс, а в нужном нам месте поставить true. Но мне говорили, что если добавляем всякие такие флаги то это служит нарушением SRP.
2) Создать метод getUsersSorted, например. Но как по мне, это тупо копирование метода getUsers с добавлением ордер бай.

Хотел бы спросить у знающих, как и почему лучше сделать?
  • Вопрос задан
  • 1159 просмотров
Подписаться 8 Простой 5 комментариев
Решения вопроса 1
@vista1x
Сделайте общий метод getUsersQuery(), который просто возвращает пользователей без какой либо сортировки. Свой метод getUsers() измените так, что бы он использовал первый метод. Плюс, добавьте метод getUsersSorted(), где будете возвращать данные, отсортированные в нужном виде. Не зная структуры проекта сложно написать какие то примеры кода, но я бы сделал примерно так:

function getUsersQuery() {
    // ...
}
function getUsers() {
    return getUsersQuery()->orderBy('id');
}
function getUsersSorted() {
    return getUsersQuery()->orderBy('name');
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 7
ThunderCat
@ThunderCat Куратор тега PHP
{PHP, MySql, HTML, JS, CSS} developer
Вариантов 3:
1) Добавить параметр: плюсы - просто, можно добавить гибкий параметр, например $sortField. минусы - в следующий раз понадобится менять еще и направление сортировки - прийдется снова костылить.
2) Отдельный метод - уже лучше, но все равно рано или поздно функционал надо будет менять и с параметрами что -то прийдется делать.
2.1) Передавать в качестве аргумента некий массив/объект настроек, плюсы - гибко, минусы - каждый раз надо учитывать/знать структуру объекта настроек, что не очень удобно.
3) Использовать внутренние паблик свойства объекта для настройки работы логики объекта, плюсы - не надо менять инерфейс вызова, достаточно сделать
$users->sortBy = 'order'; $users->sortDir = 'desc'; $users->getUsers();
. Минусы - сходу не вижу, у кого есть идеи - отпишитесь в комментах.
Ответ написан
@vism
Вобщем вы за ответом пришли туда, где 95% евда мидл-джуны.

Варианты ранее предложеные либо сильно меняют структуру, либо переусложняют.

Просто создаете второй метод и общее тело (формирование запроса) выносите в третий приватный/протектид метод. (вот vista1x не поленился и даже код накидал примерный)
В созданном методе заодно оставляете аргумент для сортировки.
Нужен будет еще - создаете третий.

Понимаете, что таких появится еще много - тогда уже меняете структуру, рефакторите.
Ответ написан
dmitriylanets
@dmitriylanets
веб-разработчик
public function getUsers(?UserCriteria $criteria){
//logic create query
if($criteria && $criteria->getSortedByOrder()){
//logic sorted by order, $criteria->getSortedByOrder() return null|"DESC"||"ASC"
}
else{
//default sorted
}
}
Ответ написан
@John_Nash
coder
Однозначно 1й вариант, т.к.
изменения исходного кода минимальны,
новое условие легко убирается/модифицируется
Ответ написан
Комментировать
driverx18 В вашем случае я бы последовал варианту №3 в ответе ThunderCat
Ответ написан
Комментировать
IvanTheCrazy
@IvanTheCrazy
https://en.wikipedia.org/wiki/Method_chaining вам в помощь :)
Например в Eloquent это могло бы выглядеть так (запрос с active=true так для примера):
User::where('active', true)->orderBy('name', 'ASC')
Т.е. вы по необходимости выстраиваете цепочки методов.
Ответ написан
Комментировать
@morricone85
Вообще, для того, что бы многократно использовать подобные методы, как getUsers, нужно передавать такие аргументы как:
- поле сортировки;
- направление сортировки;
- к-во выводимых элементов;
- c какого элемента начинать.

Это - необходимый минимум. Поэтому, самый практичный способ решения - передача массива настроек, как и указывает ThunderCat в своем комментарии.

То есть, как это может выглядеть:
function getUsers($arr = null) {
    if (!empty($arr['order'])) {
        $order = $arr['order'];
    }  else {
        $order = 'primary column';
   }
...
}


А, при вызове метода, например, так:
getUsers('order' => 'date_created', 'limit' => 50);
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы