Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Вопрос к матерым об общей идее конструкторов
Форумы портала PHP.SU » » Объектно-ориентированное программирование » Вопрос к матерым об общей идее конструкторов

Страниц (4): [1] 2 3 4 »
 

1. Mad_Alex - 21 Сентября, 2011 - 08:28:57 - перейти к сообщению
Собственно стою перед большим проектом.
Нужно решить один вопрос: ГДЕ проверять корректность ввода данных?
ДО конструктора или В конструкторе?
И придерживаться этого принципа.

Ну например:

Либо
PHP:
скопировать код в буфер обмена
  1.  
  2. $user = $_POST['user'];
  3. $user = trim($user);
  4. $user = ....
  5. $user = new user($user);
  6.  


либо

PHP:
скопировать код в буфер обмена
  1.  
  2. $user = new user($_POST['user']);
  3.  
  4. ....
  5. class user {
  6.    function __conctruct($user) {
  7.         $user = $_POST['user'];
  8.         $user = trim($user);
  9.         $user = ....
  10.         $this->login = $user;
  11. ...
  12.  


Я так понимаю что академическая теория на этот вопрос ответа не дает, только опыт?
2. EuGen - 21 Сентября, 2011 - 09:05:55 - перейти к сообщению
Правильнее поручить валидацию специальному классу (валидатору), а непосредственно саму логику обработки оставить отдельно.
То есть алгоритмически:
0. Пользователь вводит данные
1. Создается объект-валидатор и проверяется корректность данных
2. Если (1) отвечает, что данные в порядке, то далее создается объект-обработчик, который что-то делает с данными. Если (1) отвечает, что есть ошибка - о ней сообщается и происходит возврат к (0)
3. MrBeard - 21 Сентября, 2011 - 09:18:08 - перейти к сообщению
EuGen пишет:
Правильнее поручить валидацию специальному классу (валидатору), а непосредственно саму логику обработки оставить отдельно.
То есть алгоритмически:
0. Пользователь вводит данные
1. Создается объект-валидатор и проверяется корректность данных
2. Если (1) отвечает, что данные в порядке, то далее создается объект-обработчик, который что-то делает с данными. Если (1) отвечает, что есть ошибка - о ней сообщается и происходит возврат к (0)

вопрос по теме - а если существует некое большое количество классов с иерархией, входящие данные для которых различны, и проверки на валидность, соответственно, тоже, то на каждый такой класс нужно городить отдельный класс-валидатор, или создать царь-класс-валидатор, который будет иметь кучу методов проверки на каждый пользовательский класс, или всё же лучше в классах создать метод типа
PHP:
скопировать код в буфер обмена
  1. private function isValid($data)
  2. {
  3.     .....
  4.     return {true | false};
  5. }

я просто интересуюсь, потому что не соображу, какой вариант в PHP будет наиболее прозрачным и легко используемым...
4. EuGen - 21 Сентября, 2011 - 09:26:44 - перейти к сообщению
Как правило, использовать только "царь-класс" неудобно и нецелесообразно. Я поступаю так - у меня действительно есть базовый класс-валидатор, однако же содержит он лишь общие методы проверки данных, которые с большой вероятностью, будут встречаться широко. А специфичные валидаторы наследуются от него и, возможно, переопределяют при наследовании некоторые его методы.
5. caballero - 21 Сентября, 2011 - 10:38:56 - перейти к сообщению
Проверять валидность в конструкторе - абсурд. Ты создаешь екземпляр класса
разумеется уж валидного. Если ты проверяешь в конструкторе ты УЖЕ создал экземпляр. А если он не валидный и что - прибивать его?
Вообще в конструкторе не принято выполнять действия которые могут вызывть ошибку или исключение (ходить в базу например) - задача конструктора - проинициализировать члены класса.

Плодить иерархию валидаторов - это значит писать "индусский" код и противоречить принципу инкапсуляции.

Самое грамотное - создать в классе СТАТИЧЕСКИЙ метод который будет валидировать данные и возвращать екземпляр класса или там null или false или исключение выбрасывать. Тем более что статический метод будет иметь доступ к приватным членам класса. Да и не нужны в большинстве случаев специфические валидаторы.
В случае с юзером - статический метод login(name,pass)
либо возвращает екземпляр юзера после проверки в БД, либо например строку с описанием ошибки.
6. MrBeard - 21 Сентября, 2011 - 11:39:30 - перейти к сообщению
caballero пишет:
Проверять валидность в конструкторе - абсурд. Ты создаешь екземпляр класса
разумеется уж валидного. Если ты проверяешь в конструкторе ты УЖЕ создал экземпляр. А если он не валидный и что - прибивать его?
Вообще в конструкторе не принято выполнять действия которые могут вызывть ошибку или исключение (ходить в базу например) - задача конструктора - проинициализировать члены класса.

Плодить иерархию валидаторов - это значит писать "индусский" код и противоречить принципу инкапсуляции.

Самое грамотное - создать в классе СТАТИЧЕСКИЙ метод который будет валидировать данные и возвращать екземпляр класса или там null или false или исключение выбрасывать. Тем более что статический метод будет иметь доступ к приватным членам класса. Да и не нужны в большинстве случаев специфические валидаторы.
В случае с юзером - статический метод login(name,pass)
либо возвращает екземпляр юзера после проверки в БД, либо например строку с описанием ошибки.


я просто почему спрашивал... видел достаточно кода(на яве или шарпах), где проверка валидности данных проходила исключительно внутри класса объекта, и при некорректности просто бросалось исключение, в том числе при первичном заполнении пустого объекта. А во внешнем коде ни о каких проверках уже не было и речи.
С другой стороны, я читал где то о проектировании приложения так, что все данные проверяются сразу на входах, а внутри приложения проходят ТОЛЬКО валидные данные, которые больше нигде не проверяются.

Вот и хотел узнать, как в PHP удобнее или правильнее поступать)
7. Mad_Alex - 21 Сентября, 2011 - 11:56:54 - перейти к сообщению
caballero пишет:
Самое грамотное - создать в классе СТАТИЧЕСКИЙ метод который будет валидировать данные и возвращать екземпляр класса или там null или false или исключение выбрасывать. Тем более что статический метод будет иметь доступ к приватным членам класса. Да и не нужны в большинстве случаев специфические валидаторы.
В случае с юзером - статический метод login(name,pass)
либо возвращает екземпляр юзера после проверки в БД, либо например строку с описанием ошибки.



Итак получится что-то такое? Сорь если напишу глупость. Улыбка

PHP:
скопировать код в буфер обмена
  1.  
  2. if(user::valid($_POST['user'],$_POST['pass'])) new user($_POST['user']);
  3.  
  4.  
  5.  
  6. class user {
  7.  
  8.    static function valid($username,$pass) {
  9.         .....
  10.         return true;else return false;
  11.         }
  12.  
  13.    function __conctruct($user) {
  14.         $this->login = $user;
  15.         .....
  16.  

(Добавление)
Туплю Недовольство, огорчение

Так?

PHP:
скопировать код в буфер обмена
  1.  
  2. if ($user = valid($_POST['user'],$_POST['pass'])) {
  3.       ....Welcome $user->login!.....
  4.       }
  5. else {
  6.       ....какой кошмар неверный логин/пароль....
  7.       }
  8.  
  9.  
  10.  
  11. class user {
  12.  
  13.    static function valid($username,$pass) {
  14.         .....
  15.         return new user($username); //возвращаем экземпляр
  16.         else return false; //ругаемся
  17.         }
  18.  
  19.    function __conctruct($user) {
  20.         $this->login = $user;
  21.         ....
  22.  
8. DeepVarvar - 21 Сентября, 2011 - 12:35:29 - перейти к сообщению
Гон...
EuGen уже сказал как правильно поступить.
9. caballero - 21 Сентября, 2011 - 13:07:04 - перейти к сообщению
Цитата:
я просто почему спрашивал... видел достаточно кода(на яве или шарпах), где проверка валидности данных проходила исключительно внутри класса объекта, и при некорректности просто бросалось исключение, в том числе при первичном заполнении пустого объекта.


Ну, всякj люди пишут. В принципе если выбрысывать исключение то можно - тогда сборщик мусора сам уберет недоделанный класс. Но такой подход тоже некорректен. исключения должны выбрасыватся в ИСКЛЮЧИТЕЛЬНЫХ ситуациях. Например - ошибка соединения с БД или еще чего. Проверка на валидность - это бизнес-логика. Выбрасывать исключение потому что неверный логин - моветон.


PHP:
скопировать код в буфер обмена
  1. class user {
  2.  
  3.    static function login($username,$pass) {
  4.         //лезем  в  БД
  5.           if(нашли юзера){
  6.               return new user($username); //возвращаем экземпляр
  7.           }
  8.              else return false; //ругаемся
  9.          
  10.  
  11.    function __conctruct($user) {
  12.         $this->login = $user;
  13.         ....
  14.    }


вообще то статический метод может напрямую присваивать значения полям
иногда это удобнее когда десяток полей както с конструктором громоздко получатся
10. Mad_Alex - 21 Сентября, 2011 - 13:51:32 - перейти к сообщению
Выглядит эстетично. Возьму на вооружение. Сенкс!



caballero пишет:
вообще то статический метод может напрямую присваивать значения полям иногда это удобнее когда десяток полей както с конструктором громоздко получатся


А подробнее на эту тему можно?
Чем статический метод предпочтительнее конструктора на большом количестве полей?
11. Stierus - 21 Сентября, 2011 - 13:52:50 - перейти к сообщению
caballero, я с вами не согласен в последнем вопросе Улыбка Ф-я должна иметь четкий api и если она возвращает объект класса user - то возвращать false в хз каких ситуациях - это истинный моветон. Этот false не дает понять, почему он вернулся - нет такого пользователя или пароль не подошел или база упала ... из за чего false ? Так что если возвращается объект - должен возвращаться либо он, либо null, никаких смешений типов не допускается, а все ситуации, когда user не может быть отдан - должны вызывать exception соответствующего типа.

по поводу проверки - очень часто узнать, как валидировать переменную, знает только класс, которому она нужна - именно поэтому валидации, зачастую, внутри классов.
12. caballero - 21 Сентября, 2011 - 14:00:42 - перейти к сообщению
Цитата:
caballero, я с вами не согласен в последнем вопросе Ф-я должна иметь четкий api и если она возвращает объект класса user - то возвращать false в хз каких ситуациях - это истинный моветон. Этот false не дает понять, почему он вернулся - нет такого пользователя или пароль не подошел или база упала ... из за чего false ? Так что если возвращается объект - должен возвращаться либо он, либо null, никаких смешений типов не допускается, а все ситуации, когда user не может быть отдан - должны вызывать exception соответствующего типа.


Самое простое возвращать строку с описанием ошибки (null ничем не лучше false)
Смешение типов в PHP нормально - это нетипизированный язык
а вот исключения там где можно сделать нормальную обработку как раз не лучшее решенире


Цитата:
Чем статический метод предпочтительнее конструктора на большом количестве полей?



тем что вы берете данные и прямо присваиваете их членам класса

не нужно писать конструктор с десятком параметром а потом в конструкторе десяток переприсвоений этих параметров внутренним переменным
13. Stierus - 21 Сентября, 2011 - 14:08:00 - перейти к сообщению
Цитата:
Самое простое возвращать строку с описанием ошибки (null ничем не лучше false)

null - это пустое значение, тоесть ничего не найдено, false - логическое нет ... разница в подсветке ide, декларации интерфейсов (проверка соответствия интерфейсу), правильном заполнении phpdoc

пример практический:

interfase в вакууме
function test(tesClass $class);

так вот если в ф-ю test передать false - будет плохо, если null - вполне нормальная ситуация
(Добавление)
exception - исключительная ситуация. При попытке авторизации ваш логин заранее фигня, я даже пробовать не буду его авторизовывать - это и есть исключительная ситуация, сама ф-я не знает, что с ней сделать, она кидает badloginException, а что с ним будет делать вызывающая ф-я - ее не волнует. вызывающая ф-я может вывести сообщение пользователю, может записать в логи или отправить письмо администратору - да хоть 404 выдать - функция логина не должна об этом думать, но проинформировать вызывающую сторону она обязана - это она и делает с помощью исключений.
14. EuGen - 21 Сентября, 2011 - 14:13:43 - перейти к сообщению
caballero пишет:
Смешение типов в PHP нормально

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

Возвращать непонятно что - плохо, лучше всегда использовать возможность вызвать исключение.
15. caballero - 21 Сентября, 2011 - 14:27:32 - перейти к сообщению
Цитата:
сли Вы желаете писать в хорошем стиле, этого следует избегать. В таком случае Вы всегда будете знать что ожидать от того или иного метода класса.

я и так знаю что от него ожидать это программа а не лотерея.

Цитата:
Возвращать непонятно что - плохо, лучше всегда использовать возможность вызвать исключение.


Не непонятно что а вполне определенные изветсные наперед значения
либо клас User проверяем instance of
либо строку

использование исключений для бизнес логики - прямой путь к спагетти коду в частонсти целой этажерке проверок что за исключение

 

Powered by ExBB FM 1.0 RC1