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
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737 Форумы портала PHP.SU :: PHP 7 Использование контроля скалярных типов [2]
Покинул форум
Сообщений всего: 463
Дата рег-ции: Июнь 2012 Откуда: Санкт-Петербург
Помог: 5 раз(а)
Интересные вы обсуждения ведёте, однако магические методы точно использовать не хорошо..
teddy пишет:
$products = $dbh->query('SELECT name, price FROM products');
$products->setFetchMode(PDO::FETCH_CLASS, 'Product');
Этот код не полный там не хватает наверно execute... чтобы он работал
Однако всё равно не думаю, что стоит пользоваться этим механизмом PDO, если он требует public переменные или __set ... начал читать одну из книжек по ООП "Быстрая разработка программ" от Роберта Мартина, пошарил по интернету...
Еще точно не определился, как именно реализую этот класс, времени не было, но завтра отпишу, что получилось.
PS: не думал, что может быть так сложно правильно реализовать достаточно простой класс, следуя всем принципам ООП. Однако, почитав немного поглубже про принципы, шаблоны... понял, что моё понимание было достаточно узким и не полным относительно этих принципов и ООП в целом.
LIME
Отправлено: 24 Апреля, 2016 - 00:23:18
Активный участник
Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010
Помог: 322 раз(а)
Ниче не читал все пофиг
Увидел что догуглил до дядюшки Мартина
Дядя Мартин крут
И его быстрая разработка лучшее Prizma топаешь в нужном направлении... так держать
Еще grasp
Если дядюшку Мартина асилишь (Добавление) Prizmaтеди не слушай
Он ошибается
teddy
Отправлено: 24 Апреля, 2016 - 01:28:02
Участник
Покинул форум
Сообщений всего: 1462
Дата рег-ции: Апр. 2013
Помог: 91 раз(а)
Prizma пишет:
однако магические методы точно использовать не хорошо..
Это кто сказал? Причины в студию, пруф, что это всегда зло. Нужно использовать, но с умом. А вообще выстрелить в ногу можно всякими инструментами, даже полезными, если разработчик плохо понимает с чем имеет дело.
Prizma пишет:
Этот код не полный там не хватает наверно execute... чтобы он работал
Конкретно в этом примере execute не нужен.
LIME пишет:
теди не слушай
Он ошибается
Я прекрасно понимаю причины твоих возражений касательно __set и отчасти ты прав, НО:
По поводу "Сетеры это лишнее знание для клиентского кода", в данном случае это очень удобно. Но да, остается возможность переопределить значение "прямым" обращением, инкапсуляция и все такое... Эту возможность можно "прикрыть" простой проверкой в __set.
Если исходить из логики, что __set предназначен для PDO, можно проверить, если свойство пустое, то пускать на запись, значит пишет PDO а не кто то в клиентском коде. Но если значение конкретному свойству уже присвоено, бросать исключение, значит это пытается сделать не PDO. Все просто. И простоту реализации сохранили, и такие знания у клиентского кода отняли.
Покинул форум
Сообщений всего: 463
Дата рег-ции: Июнь 2012 Откуда: Санкт-Петербург
Помог: 5 раз(а)
teddy пишет:
Это кто сказал? Причины в студию, пруф, что это всегда зло. Нужно использовать, но с умом. А вообще выстрелить в ногу можно всякими инструментами, даже полезными, если разработчик плохо понимает с чем имеет дело.
teddy пишет:
По поводу "Сетеры это лишнее знание для клиентского кода", в данном случае это очень удобно. Но да, остается возможность переопределить значение "прямым" обращением, инкапсуляция и все такое... Эту возможность можно "прикрыть" простой проверкой в __set.
Причин много даже для меня:
1. Код становится менее понятным и в случае нагруженности set, менее предсказуемым
2. IDE не сможет тебе помогать (не в данном случае, тут переменные будут браться через getVar), однако если определять их в не PDO, то будет ругаться, на их область видимости.
3. Любые изменения названия полей в бд, вытекут в сложно диагностируемую ошибку, можно конечно добавить в __set проверку, что если не существует генерировать предупреждение, но зачем создавать такую почву?
4. Есть другие способы более элегантные, по реализации.
5. Сколько я в своей практике не использовал __set рано или поздно приходил, к тому, что эту часть кода приходилось переписывать, либо постоянно модифицировать.
LIME пишет:
Prizma топаешь в нужном направлении... так держать
Еще grasp
Если дядюшку Мартина асилишь
книжка интересная, по GRASP надеюсь, тоже в ближайшее время доберусь ...
Спасибо за советы.
teddy
Отправлено: 24 Апреля, 2016 - 12:53:50
Участник
Покинул форум
Сообщений всего: 1462
Дата рег-ции: Апр. 2013
Помог: 91 раз(а)
Prizma пишет:
Есть другие способы более элегантные, по реализации.
Есть, но их объяснение может привести к нескольким простыням текста и столько же текста для того что бы ответить на ваши вопросы. Если бы вы их знали не задавали такие вопросы, по этому не нужно ля-ля...
Prizma пишет:
Код становится менее понятным и в случае нагруженности set, менее предсказуемым
Как уже говорил, в данном случае мы лишь помогаем PDO сделать свою работу. Такая реализация была предложена исходя из логики, что вы делаете проект, а изучать подробности "академической" реализации это долго. И это решение в 100 раз лучше чем то с чем вы пришли на форум создавая эту тему
Prizma пишет:
Сколько я в своей практике не использовал __set рано или поздно приходил, к тому, что эту часть кода приходилось переписывать, либо постоянно модифицировать.
А я вот не помню что бы мне приходилось это делать. Наверное не там применяли
Prizma пишет:
IDE не сможет тебе помогать
Вот LIME увидел реальную проблему, она есть и это не единственная проблема если докопаться с точки зрения ООП.
Об этом много писать. Не хочу, правда. Опять же, если не понятна суть примера, см ещё раз ответ на вторую цитату в этом посте...
Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010
Помог: 322 раз(а)
Надо добавить что сетеры уместны там где установка значения это есть предметная область класса
То есть класс нужен как хранилище и только
Я говорил о любых сетерах не только магическких
Prizma
Отправлено: 24 Апреля, 2016 - 17:01:14
Посетитель
Покинул форум
Сообщений всего: 463
Дата рег-ции: Июнь 2012 Откуда: Санкт-Петербург
Помог: 5 раз(а)
Я определился, что мне нужно. Мне нужен класс Product как хранилище... я решил разделить его на 3 класса: ProductBreifInfo (содержит только 2 поля - имя и id) ProductGeneralInfo extends ProductBreifInfo (добавляются дополнительные поля) ProductFullIngo extends ProductGeneralInfo (добавляются редко используемые тяжелые текстовые поля)
не уверен стоило ли делать так или просто оставлять не сообщенные поля пустыми.
По реализации заполнения классов у меня появилось 2 варианта Вариант 1 (на примере первого класса):
Первый вариант мне кажется топорным. Второй вариант мне нравится больше, только, тогда вопрос - а стоит ли разделять класс Product - пусть есть пустые поля, они же не мешают, всегда если надо можно добавить недостающие в старый экземпляр, а не грузить всё заново.
teddy
Отправлено: 24 Апреля, 2016 - 17:16:39
Участник
Покинул форум
Сообщений всего: 1462
Дата рег-ции: Апр. 2013
Помог: 91 раз(а)
LIME
Приблизительно об этом я и говорил, о классе, экземпляры которого представляют определенный тип связанный с данными, которые подвергаются CRUD-у.
Может класс на предыдущей страничке был немного скудным, поэтому появились вопросы. Вот более ясный пример использования
$products=$storage->getList();//получили список объектов типа Product
//пример #2. insert и update
$product->setName($name);
$product->setPrice($price);
$storage->save($product);
Таким образом получаем унифицированный интерфейс обращения с продуктом и наличие соответствующего типа в коде а так же возможность локализировать некоторые стандартные вычисления(если они есть) в методах этого типа вместо того что бы дублировать их везде где используется product (Добавление)
Prizma пишет:
По реализации заполнения классов у меня появилось 2 варианта
Так у вас будет 2 цикла. Один заполнение массива, другой - для вывода данных из этого массива(через объекты которые в этом массиве). Тут явно напрашивается Traversable.
Просто если таких параметров 15-20, окей пилю в аргумент массив или объект, получается массив полученный от $q->fetch(...) идет в аргумент, а чем статический create будет лучше стандартного __construct($name, $price)?
teddy пишет:
Так у вас будет 2 цикла. Один заполнение массива, другой - для вывода данных из этого массива(через объекты которые в этом массиве). Тут явно напрашивается Traversable.
Согласен - расточительно. Почитал про итераторы.. т.е. реализовать класс class productList implements Iterator для этого дела? и помимо обязательных методов описанных интерфейсом, методы добавление удаления типа addItem, removeItem так?
LIME
Отправлено: 24 Апреля, 2016 - 18:18:43
Активный участник
Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010
Помог: 322 раз(а)
Да я вообще не об этом
Считай выше был просто псевдокод
Я о том что если с предметом надо совершать действие создать/приготовить/перекрасить то должны быть эти методы
А всякие сетеры гереты и сэйвы это детали реализации которые надо инкапсулировать
Думаю теди понял а ты просто запомни потом поймешь
teddy
Отправлено: 25 Апреля, 2016 - 00:29:53
Участник
Покинул форум
Сообщений всего: 1462
Дата рег-ции: Апр. 2013
Помог: 91 раз(а)
Prizma пишет:
т.е. реализовать класс class productList implements Iterator для этого дела?
В вашем случае проще всего использовать PDOStatement который и так Traversable с соответствующим типом fetch-а. Если создаете и заполняете экземпляр самостоятельно самый простой вариант это задействовать Generator
Prizma
Отправлено: 25 Апреля, 2016 - 00:31:10
Посетитель
Покинул форум
Сообщений всего: 463
Дата рег-ции: Июнь 2012 Откуда: Санкт-Петербург
Помог: 5 раз(а)
И так провел воскресенье, вдаваясь в тонкости ООП и разбирая несколько примеров, и вот, что получилось:
Как то так.. Для хранения экземпляров класса Product ничего лучше массива не приудмал, хотя была мысль сделать ProductList, даже написал его, но в итоге не понял в чем принципиальная разница от простого массива... разве, что добавить туда методы updateAll, deleteAll которые мне пока точно не нужны. Хотя смотря в будущее возможно всё таки к этому еще вернусь, когда буду переписывать корзину товаров, там и общая стоимость всех товаров и скидка в от суммы заказа тоже зависит...
Данные перед выходом нужно обработать (именно сами данные): перевести цены в рубли, расчитать кол-во дней до конца акции, пропарсить описание на предмет подстановки... (это те функции, которые уже реализованы на сайте, а я собственно решил переписать свой код 2-ух летней давности, со свежим взглядом). Если я правильно начинаю понимать ООП, это именно те методы, которые должны быть реализованы в классе Product? (Добавление)
еще подумываю в геттерах класса Product генерировать ошибку в случае запроса атрибута со значением равным null (т.е. те которые не определены в выбранном режиме).
Покинул форум
Сообщений всего: 2751
Дата рег-ции: Июль 2010 Откуда: Даугавпилс, Латвия
Помог: 52 раз(а)
интересное чтиво http://sergeyteplyakov[dot]blogspot[dot]ca/
ооп, солид, контракты, все что хочешь
так же много статей об ОО дизайне
и еще есть пару списков маст-рид книг, с кратким описанием, и подробные рецензии на некоторые книги
примеры в основном на C# но не думаю, что это будет проблемой
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.