Не понимаю, для чего нужны классы в PHP?
Допустим, есть function.php, в нём много много функций, выполняющих разные действия
функции частично содержат общие переменные и в некоторых случаях части их кодов совпадают.
Если все эти функции превратить в методы и засунуть в один класс, что изменится в лучшую сторону или по другому - для чего нужны классы?
Ответы
Ответ 1
Пример работы с БД:
$con = db_connect($data);
$query = db_query($con, $data);
$fetch = db_fetch($query);
Опять же, нужна глобальная переменная $con, проверка результата каждый раз и т.п.
Или вот класс:
/**
* @author
*
* @todo
*/
class Db {
private $con, $query, $fetch;
/**
*
*/
function __construct($data) {
return $this->con = db_connect($data);
}
/**
*
*/
function query($data) {
if($this->con) {
$this->query = db_query($this->con, $data);
return $this;
}
else {
throw new Exception('no connection to db');
}
}
/**
*
*/
function fetch() {
if($this->con) {
return $this->fetch = db_fetch($this->query);
}
else {
throw new Exception('no connection to db');
}
}
/**
*
*/
function __destruct() {
db_close($this->con);
}
/**
*
*/
public static function create($data) {
return new Db($data);
}
}
$Db = Db::create('host:localhost;login:1234...');
$fetch = $Db->query('SELECT * FROM db')->fetch();
Простенько запускаем, делаем запрос и выводим результат. Красиво, удобно.
Ответ 2
(Резюме: классы нужны, чтобы абстрагироваться от сложности задания.)
Вы серьёзно не знаете, для чего нужны классы? Хм. Ну ладно.
Давайте подумаем: что такое программирование? Программирование -- это производство
Я имею в виду не учебные задания в стиле «введите строку и посчитайте в ней количеств
пробелов». Я имею в виду реально большие проекты. В них не так уж часто встречаютс
особо умные куски кода, зато функциональности много, она не обязательно логично устроена (особенно часто такое бывает, если вы конструируете интерфейс пользователя), и, что немаловажно, проект поддерживают не гении, вроде всех на этом сайте, а обычные программисты.
Это значит, что большая часть времени жизни кода уйдёт на его поддержку, а не начальную разработку.
Гении (и начинающие программисты тоже, как ни странно) не любят доводить что-то д
совершенства. Они напишут прототип в виде одной офигенно сложной функции, и voila!
задание выполнено. В функции есть тысяча хитростей и зависимостей, которые гению просто держать в голове. Но завтра гений заболеет, уйдёт в запой или вообще уволится — и внезапно код должны поддерживать самые обыкновенные обыкновенные программисты, из мяса и костей.
А обыкновенному программисту нелегко работать с длинной сложной функцией, при одно
взгляде на неё начинает болеть голова. Он не может держать в голове сразу миллионы поняти
и зависимостей! И тут внезапно на помощь приходят классы. Классы позволяют уменьшит
сложность. Когда программист разрабатывает класс, он, конечно, думает обо всём класс
и держит в голове сразу весь класс. Но когда он разрабатывает другие классы, он думае
больше не в терминах «я вызову функцию X, и она установит переменную Y», а в термина
классов: «я беру возраст пользователя», «я рисую эту картинку». Теперь голова болит гораздо меньше: вместо того, чтобы думать о всех функциях в проекте одновременно, программист думает только о немногих публичных функциях немногих публичных интерфейсов. Таким образом, в его коде меньше зависимостей: он не должен думать (вернее должен не думать!) о конкретной реализации возраста пользователя, или там отрисовки картинки, он может про это забыть. Его код становится проще, этот код легче понимать, тестировать и поддерживать.
Кроме того, он больше не должен думать что-то типа «я добавляю пользователя в списо
модераторов, для этого мне надо обновить вот этот массив, вот ту хэш-таблицу, поставит
флаг для обновления базы данных и не забыть ещё увеличить счётчик версий». Он прост
говорит: «таблица модераторов, добавь-ка в себя вот этого пользователя!» То есть тепер
можно думать не в терминах внутренних структур данных, а в терминах семантики: программист пишет прямо то, что он хочет выразить. Несмотря на то, что в языке не было раньше конструкций для выражения его мыслей. Мы видим, что программист на самом деле расширяет язык под свою предметную область, и может легко и адекватно выражать своё намерение. Такой код не только легче писать, но и легче поддерживать.
При этом эффективность кода может падать по сравнению кодом, учитывающим особенност
реализации других классов, но мы сознательно идём на эту жертву: наша цель — чтобы код стал проще, яснее, чтобы он говорил сам за себя!
Обратите внимание, что этот подход — развитие процедурного подхода: там мы складывал
код в процедуры, чтобы абстрагироваться от кода одной процедуры во время разработк
другой (и код, который опирается на конкретику реализации, обычно считается плохим, потому что он не уменьшает количество абстракций, которые нужно держать в голове). Так и при объектном-ориентированном подходе уменьшается, в свою очередь, количество функций, которые надо держать в голове.
Кроме того, ООП даёт другие плюшки, в виде наследования и полиморфизма, которые
однако, кажутся мне концептуально менее важными. Хотя и очень приятными в использовании.
Таким образом, для маленького проекта, для которого вы можете держать все функци
в голове, можно отказаться от использования классов. Но для достаточного большого, серьёзного проекта без помощи классов для уменьшения сложности не обойтись.
PS: Для разработчиков на C: в самом деле, можно уменьшать сложность и по-другому
например, не выносить нерелевантный код в заголовочные файлы. Классы в языках, которые их поддерживают, предоставляют явное средство управления сложностью, в отличие от неявного, осуществляемого в C.
Ответ 3
ООП - вообще, а не только в PHP - это всего лишь навсего другое представление процедурного программирования.
Компилятор (интерпретатор) при парсинге классов заменяет все на обычные функции.
Было:
class ClassA {
public $item;
public function MethodA() {};
}
Стало:
ClassA = object {
$item;
}
function MethodA(ClassA $object) {};
И все вызовы, соответственно, заменяются: ClassA->methodA() => methodA(ClassA);
Т.е. в интерпретируемых языках обратное преобразование (из класса в функции) постоянно занимает некоторое время (в компилируемых занимает только на этапе компиляции).
Зачем тогда же вводят это ООП, в том числе и в PHP?
1) Уже было сказано - достаточно в одно месте сделать необходимые вычисления (проверки
тригеры и т.д.) - и не надо будет об этом заботиться дальше. Да и менять потом придется в одном месте - в классе, а не искать и исправлять по всем файлам
2) Сопровождать этот код (с использованием ООП) в больших проектах - намного проще, чем искать по всем функциям по всем файлам.
Можно, конечно, разделить функции по смыслу и запихать их в соответствующие файлики
но чем тогда этот подход будет отличаться от ООП? Отличаться будет, конечно, т.к. у ООП еще куча своих плюшек, но в этом плане - аналогия почти полная
3) Именование - в различных классах имена переменных могут пересекаться как угодно. Используя глобальные переменные вы этого не добьетесь.
4) Проектируя какой-нибудь объект вы ожидаете от него определенного поведения. Есл
использовать обычные функции, то где будет уверенность, что нужную сейчас глобальную переменную вы не поменяете где-нибудь еще в какой-нибудь левой функции без предупреждения?
5) и 6) и 7) и т.д. - все в книгах расписано, всего здесь не напишешь.
Главное - почти все, что реализуется с использованием ООП можно реализовать использу
функции. И при небольшом количестве строк кода функции будут заметно выигрывать у ООП, а не правильно используя ООП можно вообще завести проект в дебри.
Ведь вы же в магазин не на самолете летаете? И в отпуск не пешком ходите?
Так и здесь - до тех пор пока что-то замечательно справляется с поставленной задачей
то зачем это что-то менять? Но это именно "до тех пор пока что-то замечательно справляется с поставленной задачей".
Ответ 4
В чём-то с вами я согласен, сам классами пользоваться не спешу, хотите вы этого ил
нет, но классы - это тоже хорошая нагрузка на сценарий. Вообще классы удобны, когд
приходится как-то группировать функции(а в них они методы), например, может быть мето
с одинаковым названием в разных классах, но с разным предназначением и кодом. Сам лично начал изучать классы тогда, когда пришлось править чужой код. Пользоваться классами или нет - решать вам, но а для чего они всё же нужны, вроде как знаю, понимаю, а описать не могу, но в основном для какой-то классификации.
Ответ 5
Суть не сколько в классах, а конкретно в ООП, и потребности его использования!
Допустим есть у меня файл function.php
Дело в том что он у всех есть, не зависимо от того используется ли ООП в проект
или нет, радовой функционал не выбросишь, как не крути.
Ну и конечно как высказались выше "группировка функций по логическим задачам".
главное, это очень удобно.
Ответ 6
Если вы пишете простую программу, ООП не нужен.
I. Простую программу на пару сотен строчек можно никак не организовывать, и вы н
почувствуете необходимости в ООП. Это одна из проблем при обучении ООП: в нём реальн
возникает необходимость, только если вы работаете со сложной системой, а примеры почему-то всегда используют бестолковые, на пару строчек. Разумеется, это вызывает неприятие.
Для простого смертного прикладного программиста (ака любителя императивного кода
обычно самым простым кодом является процедурное программирование. Если вам для ваших задач хватает его — пользуйтесь им.
II. Во многих ответах выше описывают не объектно-ориентированное программирование
а "недо-объектное" программирование, когда функции просто раскидываются по классам
В итоге, вместо $foo = foo_create(); foo_call_baz($foo, 123, $baz) вы пишете $foo = new Foo(); $foo->call_baz(123, $baz). Разница исключительно на уровне синтаксиса: ставить первый аргумент функции в начале или посередине, использовать для работы с объектами функции с префиксом или писать "присоединять" название функции к переменной.
Подобное "недо-объектное" программирование — это естественный следующий шаг посл
процедурного программирования. Несмотря на весьма небольшие отличия, работать с объектам
несколько удобнее: все функции собираются в одном месте, ну нужно использовать префикс
для функций, чтобы избежать конфликтов между модулями, среда разработки всегда точно подсказывает, что можно сделать с объектом. И, разумеется, вы можете воспользоваться инкапсуляцией, чтобы скрыть от пользователя поля, в которые он не должен залезать без спроса.
III. Следующий шаг возникает, когда сущности начинают выстраиваться в иерархию. Например
есть объект (хоть в процедурном, хоть в объектом понимании) "база данных", и вы хотит
выполнить запрос. Но база данных не может быть абстрактной, всегда надо использовать конкретную СУБД: MySQL, SQL Server и т.п. Основные методы работы с этими базами данных похожие, и хочется с ними работать по-одинаковому, чтобы можно было при необходимости менять СУБД, не меня код.
Для процедурного программирования естественный ход — это добавить в объект свойств
"СУБД" и в функции do_sql_query добавить огромный-преогромный switch по всем вариантам. Поддерживать такой код становится невероятно сложно, в каждой функции приходится обрабатывать все возможные варианты для всех возможных СУБД.
И вот здесь на помощь приходит объектно-ориентированное программирование. Тепер
вы можете использовать наследование, чтобы построить классы в стройные иерархии, и полиморфизм, чтобы организовать вызов "одинаковых" методов в зависимости от положения класса в иерархии.
Так как человеку естественно думать в терминах объектов, а не функций, то объектно-ориентированно
программирование хорошо подходит для описания сущностей. Разумеется, те же сущности есть в и процедурном, и в объектом программировании, но именно со всеми возможностями объектно-ориентированного программирования приходит свобода реализовать код красиво и лаконично.
IV. В определённый момент даже объектно-ориентированного программирования начинае
не хватать: оно предоставляет огромную свободу, и код снова превращается в мешанин
из иерархий и виртуальных методов, которые вызываются как попало. Тут на спасение приходят шаблоны проектирования, которые описывают, как с помощью объектно-ориентированного программирования можно эффективно организовывать код, как избегать чрезмерной сложности и делать так, чтобы код был понятен остальным.
Другое направление — обобщённое программирование, когда с объектами разных типо
можно работать одинаковым или похожим способом.
При любой парадигме в сложных программах неизбежно возникают модули и другие способы организации кода.
Какой язык — объектно-ориентированный или процедурный — значения не имеет. В объектно-ориентированном стиле можно писать на процедурном языке и наоборот.
Кроме того, существует множество парадигм программирования: функциональное программирование
логическое программирование и другие. Это уже не привычное императивное программирование, но некоторые аспекты того же функционального программирования начинают перебираться в традиционно императивные языки, что позволяет пользоваться многими интересными возможностями.
Ответ 7
Полностью поддерживаю @lampa .
В функцию класса можно спокойно засунуть все необходимые проверки. Плюс вспомните
что обычно сайт состоит не из одной страницы, а, к примеру, из 10, и на каждой буде
эти 3 строчки + 10 строк проверки входящих параметров, подстановки параметров в строк
запроса, проверки результата... И при изменении одной из этих строчек придется менять ее на всех 10ти страницах. А если у вас класс - меняем это только в одном месте и все, на всех страницах будет использоваться уже исправленная или дополненная функция. Как раз класс работы с базой данных это очень хороший пример полезности использования ООП.
а представьте, что вы написали проект, который работает не только с MySQL, но и ещ
может работать с postgresql или sqlite? Что же на каждой странице делать проверку
какой бд мы работаем в данном случае? фу-фу-фу-фу! Для этого есть class! В нем делаем одну переменную и в зависимости от ее значения используем тот или иной метод работы с базой. Ведь правда же удобно? ;)
Ответ 8
Чтобы проектировать и писать сложные вещи. Почитайте книгу Мэтт Зандстра "PHP. Объекты
шаблоны и методики программирования", если собираетесь использовать ООП подход в полную силу.
Комментариев нет:
Отправить комментарий