[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Как переписать множество 'if' условий в ООП
Страницы: 1, 2, 3
acerrusm
Привет. Есть такой метод:

public function validate($label, $type, $validators, $data)
{
if ($validators != false)
{
foreach ($validators as $validator) {
if ($validator == 'required')
{
self::validateRequired($data, $label);
}
elseif($validator == 'future')
{
self::validateFuture($data, $label);
}
elseif($validator == 'aboveZero')
{
self::validateAboveZero($data, $label);
}
}
}
}


Переменная $validator содержит строку с названием валидации. В зависимости от содержимого $validator вызывается нужная функция. Я еще давно где то прочитал, что это некрасивое решение, и его нужно переделать в соответствии с ООП. Там еще говорилось что то про паттерны. Но блин не помню. С паттернами практически не знаком.

Так как же все таки 'правильно' переписать такой код?
redreem
че-то есть подозрения, ООП тут не причем.
acerrusm
Цитата (redreem @ 21.03.2016 - 18:58)
че-то есть подозрения, ООП тут не причем.

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

public function validate($label, $type, $validators, $data)
{
foreach ($validators as $validatorName) {
$validator = ValidatorFactory::get($validatorName);
$validator->setLabel($label);
$validator->setData($data);
$validator->check();
}
}



_____________
Люди, имеющие низкий уровень квалификации, делают ошибочные выводы, принимают неудачные решения и при этом неспособны осознавать свои ошибки в силу низкого уровня своей квалификации
acerrusm
Цитата (chee @ 21.03.2016 - 19:57)
public function validate($label, $type, $validators, $data)
{
foreach ($validators as $validatorName) {
  $validator = ValidatorFactory::get($validatorName);
  $validator->setLabel($label);
  $validator->setData($data);
  $validator->check();
}
}

chee, спасибо!
А в методе get($validatorName) все равно придется делать проверку вроде if ($validatorName == 'required').. ?
sergeiss
Цитата (acerrusm @ 21.03.2016 - 21:53)
Так как же все таки 'правильно' переписать такой код?

Почему бы просто не использовать
switch( $validator ) {
case 'required': ....

break;
....

}


_____________
* Хэлп по PHP
* Описалово по JavaScript
* Хэлп и СУБД для PostgreSQL

* Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги.

* "накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С)

user posted image
acerrusm
Цитата (sergeiss @ 21.03.2016 - 20:10)
Цитата (acerrusm @ 21.03.2016 - 21:53)
Так как же все таки 'правильно' переписать такой код?

Почему бы просто не использовать
switch( $validator ) {
case 'required': ....

break;
....

}

sergeiss, я тоже как вариант предложил, но для работодателя это тоже самое, что и if, else
Ron
Цитата (acerrusm @ 21.03.2016 - 23:13)
но для работодателя это тоже самое, что и if, else

А на самом деле это хуже чем if else. =) Менее прозрачно, засчет break-ов. Требует при дебаге слишком много внимания. Короче бяка, отстой, мастдай.

acerrusm, посмотри петтарн "фабрика", chee тебе ж намекнул как бы. )))

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

Я бы немного подругому, правда, сделал, чем классическая фабрика. Через интерфейс. Но это уже мелочи суть от этого не поменяется.
Guest
Идея такая, что если if должен быть в коде – то он должен быть там только один раз. Например, в ValidatorFactory::get().
А так как PHP это динамический язык – то технически и от if можно избавиться:
$validatorClassName = 'Validator' . ucfirst($validatorName);
return new $validatorClassName();

Или как-нибудь с помощью магических методов. Может интервьюерам нужна была такая магия?

acerrusm,
Непонятно где находится твоя public function validate. Если оно встречается в коде только один раз – то по большому счету это ок. А если, например, в каждой в модели – то конечно не ок.
acerrusm
Цитата (Ron @ 21.03.2016 - 20:32)
Цитата (acerrusm @ 21.03.2016 - 23:13)
но для работодателя это тоже самое, что и if, else

А на самом деле это хуже чем if else. =) Менее прозрачно, засчет break-ов. Требует при дебаге слишком много внимания. Короче бяка, отстой, мастдай.

acerrusm, посмотри петтарн "фабрика", chee тебе ж намекнул как бы. )))

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

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

Да, давно уже пора паттерны изучить. Вот эту книгу хочу почитать.
acerrusm
Цитата (Guest @ 21.03.2016 - 20:38)
Идея такая, что если if должен быть в коде – то он должен быть там только один раз. Например, в ValidatorFactory::get().
А так как PHP это динамический язык – то технически и от if можно избавиться:
$validatorClassName = 'Validator' . ucfirst($validatorName);
return new $validatorClassName();

Или как-нибудь с помощью магических методов. Может интервьюерам нужна была такая магия?

acerrusm,
Непонятно где находится твоя public function validate. Если оно встречается в коде только один раз – то по большому счету это ок. А если, например, в каждой в модели – то конечно не ок.

Тут весь код
Zzepish
Я бы сделал через динамическую реализацию!

$type = 'function'

if(method_exists($this, 'validate'.$type))
self::'validate'.$type($data)
Ron
Zzepish, а если у тебя будет сотня валидаторов разных? Все в один класс запихнешь? =) Да еще и вспомогательные методы, если валидатор будет сложным. Такая дичайшая каша получится, ты в этом классе просто утонешь при малейшем дебаге/доработке.

Потом Вася захочет дописать свой валидатор к имеющейся коллекции и чего ж ему, бедолаге, делать!? Ты ж обикаешься! biggrin.gif

Фабрика это и есть динамическая реализация, только с нормальной архитектурой. =) Прчем она здесь настолько явная, что тут же показывает уровень владения ООП. Фабрика один из самых популярных патторнов группы порождающих. Не менее известный, чем Singletone. Если его не знаешь, то скорее всего вообще ничего не знаешь о паттернах и не слышал никогда. wink.gif

Zzepish
Ron
Цитата
Zzepish, а если у тебя будет сотня валидаторов разных? Все в один класс запихнешь? =) Да еще и вспомогательные методы, если валидатор будет сложным. Такая дичайшая каша получится, ты в этом классе просто утонешь при малейшем дебаге/доработке.

Не смеши. Нафига тебе абстрактный класс?

В предложенном мной примере- нет ничего тяжелого.
Про фабрику я вкурсе. А если я не знаю какого-то паттерна, то я не считаю это трагедией.
Ron
Zzepish, мы тут про ООП, если что. wink.gif

Цитата (Zzepish @ 22.03.2016 - 00:27)
Не смеши. Нафига тебе абстрактный класс?

Не нравится, не делей через абстрактный класс. Я бы сделал валидаторы через интерфейс, например. Не нужно воспринимать паттерны настолько буквально. Тебе показали идею, как сделать архитектурно правильно. Реализация может отличаться от википедии.

Цитата (Zzepish @ 22.03.2016 - 00:27)
Про фабрику я вкурсе. А если я не знаю какого-то паттерна, то я не считаю это трагедией.

<:-)


Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2025 Invision Power Services, Inc.