Я PHPer, и я не пишу объектно-ориентированный код.
Каковы преимущества OO над процедурным кодом, и где я могу научиться применять эти идеи для PHP?
Это не поможет вам автоматически. Вы можете писать хуже программы «OO», чем структурные программы, и наоборот. ООП – это инструмент, который позволяет создавать более мощные абстракции.
Объекты помогают изолировать ваш код между различными разделами, поэтому, если вам нужно внести изменения в один раздел, вы можете быть уверены, что это не повлияет на другие разделы: свободная связь.
Затем, когда вы это сделаете некоторое время, вы начнете находить, что объекты, созданные для одного приложения, также полезны в других, и вы также начинаете получать более качественное повторное использование кода. Итак, новое приложение имеет часть уже выполненной работы и использует проверенный временем код: программное обеспечение построено быстрее с меньшим количеством ошибок.
Люди расскажут вам разные вещи о ООП, с разных точек зрения. Но если вы хотите сформировать собственное мнение, а не брать чье-то чужое, я предлагаю прочитать «Объектно-ориентированное программное обеспечение» Бертран Майер.
По сути, он использует методы программирования, отличные от ООП, и анализирует их основные недостатки. Затем он получает альтернативную технику, которая устраняет эти недостатки. Иными словами, он выводит ООП из первых принципов. Это замечательная работа и очень удобная.
Прочтите это, вы узнаете, почему, когда и что в какой-то мере вы можете поддержать рассуждения.
Объекты помогают инкапсулировать сложность. Для большинства PHP-программирования невозможно написать хороший, чистый код для любого достаточно сложного приложения. Написание OO PHP помогает вам вставить этот код в свой собственный ящик, изолируя его от всего остального. Это имеет несколько преимуществ.
Poll::Display()
) до полностью реализовать то, что может сделать приложение, что упростило работу с моей домашней страницей. Помните об этом – OO в PHP (даже PHP5) не очень хорошо OO по сравнению с языком, например Python или Ruby. Модель «все-есть-объект» в Python – это то, что заставило меня программировать OO на самом деле щелкнуть для меня – и, будучи бывшим программистом PHP (и дважды сертифицированным инженером Zend), я настоятельно рекомендую изучить OO Python, если вы хотите понять, что OO это все о. Это поможет вам лучше писать PHP-код, по крайней мере.
Да, если вы действительно это понимаете.
Это помогает вам визуализировать, как части более крупной системы могут взаимодействовать друг с другом. Это очень полезно на уровне разработки.
Если вы просто пишете несколько строк кода, единственное преимущество, которое вы получите, состоит в том, что, как правило, немного проще использовать библиотеку, разбитую на хорошо продуманные объекты, чем просто функции.
Чтобы эффективно использовать его, вам также необходимо следовать разумным правилам проектирования OO. Всегда инкапсулируйте ВСЕ ваши данные, используя множество небольших классов, никогда не занимающихся большими классами. Наличие класса делает вашу работу за вас, вместо того, чтобы запрашивать данные и выполнять работу вне класса и т. Д.
Скорее всего, это не поможет вам какое-то время, и, возможно, никогда, если вы всегда делаете небольшие веб-сайты (я не могу сказать это точно, я действительно не делаю php), но со временем и по крупным проектам он может быть неоценимым.
Одна вещь, о которой никто не упоминал, заключается в том, что OO-код облегчает написание читаемого кода:
sherry.changePhoneNumber(); phoneCompany.assignNewPhoneNumberTo(sherry); sherry.receive(new PhoneNumber().withAreaCode("555").withNumber("194-2677"));
Я получаю странное удовлетворение от такой эстетики.
Огромная победа для меня – наследование или создание объекта, который ведет себя почти точно как другой, но с несколькими отличиями. Вот пример из моего офиса:
Нам нужен код для обработки TIFF-файлов, которые клиент отправил нам, конвертировал их в стандартный формат, вставлял некоторую информацию о файле в базу данных, а затем отправлял сообщение о результатах. Я написал это в наборе классов (в Python, но идея такая же). Класс «fetcher» получил электронные письма из почтового ящика POP3 и передал их классу «контейнер», который знал, как читать вложения из электронной почты. Этот класс передал каждое изображение в класс «file object», который выполнил необходимую обработку.
Ну, однажды мы получили клиента, который хотел отправить PDF-файлы. Я подклассифицировал класс «файл-файл TIFF» и переписал функцию «normalize», чтобы вместо этого взять PDF-файл, но оставил все остальные части кода нетронутыми. Он работал в первый раз, и я был очень доволен.
Изменение нашего почтового сервера означало, что мне нужно было получать электронные письма через IMAP. Опять же, я подклассифицировал «сборщик POP3», чтобы он мог говорить по протоколу IMAP. Задача решена.
Другой клиент хотел отправить нам компакт-диски, поэтому я подклассифицировал класс «контейнер электронной почты» классом «каталог файловой системы». Вуала – сделано.
В каждом из этих случаев новый код был на 95% похож на старый код. Например, класс «файл-файл TIFF» имеет около 15 методов. Класс «PDF file object» определяет ровно одно: метод, который преобразует файлы в определенном формате в наш стандарт. Все остальные получают от своего родительского класса.
Теперь вы можете определенно сделать то же самое в процедуре, например, написав:
if fileobjecttype == 'TIFF': data = <snip 30 lines of code to read and convert a TIFF file> elif fileobjecttype == 'PDF': data = <another 45 lines to read a PDF> elif fileobjecttype == 'PNG': data = <yep, another one>
Самое большое различие заключается в том, что я считаю, что вы можете сделать ООП более чистым и более организованным. Мой класс PDF выглядит так:
class PDFReader(GenericImageReader): def normalize(self): data = <45 lines to read a PDF>
вот и все. Вы можете сразу сказать, что он делает только одну вещь иначе, чем класс, на который он наследует. Это также заставляет вас – или, по крайней мере, настоятельно рекомендует вам – сделать чистые интерфейсы между слоями вашего приложения. В моем примере PDFReader понятия не имеет и не волнует, появился ли его образ из почтового ящика POP3 или компакт-диска. Сборщик POP3 абсолютно ничего не знает о приложениях, поскольку его работа – просто получать электронные письма и передавать их вместе. На практике это позволило нам сделать некоторые удивительные вещи с абсолютным минимальным количеством кодирования или редизайна.
ООП не волшебство, но это довольно фантастический способ сохранить свой код организованным. Даже если вы не используете его повсюду, это все еще умение, которое вы действительно должны развивать.
Было время, когда я впервые начал программировать, что написал пользовательский код. Он отлично работал, но его было сложно поддерживать.
Затем я узнал OO, и код, который я написал, стал легче поддерживать, проще делиться между проектами, а жизнь была хорошей … для всех, кроме моих пользователей.
Теперь я знаю истинную серебряную пулю компьютерного программирования. Я пишу код OO, но сначала я объективирую своих пользователей . Сначала рассматривать людей как объекты может показаться грубым, но он делает все намного более элегантным – вы можете написать все свое программное обеспечение для работы с четко определенными интерфейсами, а когда пользователь отправляет неожиданное сообщение, вы можете просто игнорировать его или, если отмечен флагом, означающим достаточную важность, выведите в них исключение.
Жизнь, с ОО, хороша …
Я бы сказал, что ООП подходит тем, кто думает в «объектах», где объект состоит из данных, а также функций, которые работают с этими данными.
Я бы предостерег от выхода и изучения моделей . Чтобы сделать объектно-ориентированное программирование хорошо, вам нужно научить себя думать, как объектно-ориентированный программист. Вам нужно будет понять, что вы понимаете, и можете назвать преимущества:
Это поможет вам стать лучшим программистом только в том смысле, что чем больше стилей программирования программист знает, тем больше диапазона в его репертуаре для решения проблем и написания элегантного кода. Вы не можете уйти и написать весь свой объектно-ориентированный код и автоматически иметь хороший код, но если вы действительно понимаете, как работает ООП, и вы не просто скопируете некоторые популярные шаблоны дизайна дня, тогда вы можете написать довольно хороший код, особенно при написании большого приложения.
Кажется, каждый реагирует на ваш вопрос буквально, т. Е. Конкретные выгоды / недостатки OO.
Вы должны изучить OO, но не потому, что у OO есть какая-то специальная магия, в которой вы нуждаетесь.
Более общая форма:
Я бы сказал так: если вы пишете что-нибудь сложное, вы должны кодировать концепции, о которых вы думаете, вместо того, чтобы пытаться мыслить в концепциях, которые как-то родны для используемого вами языка. Таким образом, вы делаете меньше ошибок. Формализация этих концепций называется дизайном.
Функциональное программирование позволяет определять понятия, связанные с глаголами, поскольку каждая функция по существу является глаголом (например, print ()). С другой стороны, программирование OO позволяет также определять понятия, связанные с существительными.
Я долговременный программист PHP-программист, который время от времени размышляет в объектно-ориентированном PHP. Ответ Джоэля выше – превосходное резюме преимуществ. На мой взгляд, тонкая вторичная выгода заключается в том, что она заставляет вас лучше определять ваши требования с самого начала. Вы должны понимать отношения между объектами и методы, которые будут действовать на них.
Хорошей книгой, помогающей с переходом, является «Объектно-ориентированный PHP» Питера Лавина.
alt text http://img.ruphp.com/php/oop_cover.jpg
Поразмыслить над ответом Джори:
Международная организация по стандартизации определяет инкапсуляцию как «Свойство, что информация, содержащаяся в объекте, доступна только через взаимодействия на интерфейсах, поддерживаемых объектом».
Таким образом, поскольку некоторая информация доступна через эти интерфейсы, некоторая информация должна быть скрыта и недоступна внутри объекта. Свойство таких информационных экспонатов называется скрытием информации, которое Парнас определил, утверждая, что модули должны быть разработаны, чтобы скрыть как сложные решения, так и решения, которые могут измениться.
Обратите внимание, что слово: change. Сокрытие информации касается потенциальных событий, таких как изменение сложных проектных решений в будущем.
Рассмотрим класс с двумя методами: метод a (), который является информацией, скрытой внутри класса, и метод b (), открытый и доступный напрямую другими классами.
Существует определенная вероятность того, что будущее изменение метода a () потребует изменений в методах в других классах. Также существует определенная вероятность того, что в будущем изменении метода b () потребуются изменения в методах в других классах. Вероятность того, что такие изменения пульсаций произойдут для метода a (), однако, будет обычно ниже, чем для метода b (), просто потому, что метод b () может зависеть от большего количества классов.
Эта уменьшенная вероятность воздействия пульсаций является ключевым преимуществом инкапсуляции.
Рассмотрим максимальное потенциальное число зависимостей исходного кода (MPE – аббревиатура от теории графов) в любой программе. Экстраполируя приведенные выше определения, можно сказать, что, учитывая, что две программы обеспечивают идентичную функциональность для пользователей, программа с наименьшим MPE лучше инкапсулирована, и что статистически более инкапсулированная программа будет дешевле поддерживать и развиваться, поскольку стоимость максимального изменения потенциала к ней будет ниже максимального изменения потенциала в менее хорошо инкапсулированной системе.
Рассмотрим, кроме того, язык с помощью только методов и классов, и, следовательно, нет средств скрытия информации друг от друга. Скажем, наша программа имеет 1000 методов. Что такое MPE этой программы?
Теория инкапсуляции говорит нам, что при использовании системы из n общественных узлов MPE этой системы n (n-1). Таким образом, MPE наших 1000 общественных методов составляет 999 000.
Теперь давайте разделим эту систему на два класса, каждый из которых имеет 500 методов. Поскольку у нас теперь есть классы, мы можем выбрать, чтобы некоторые методы были общедоступными, а некоторые – частными. Это будет иметь место, если каждый метод фактически не зависит от любого другого метода (что маловероятно). Предположим, что 50 методов в каждом классе являются общедоступными. Каким будет MPE системы?
Теория инкапсуляции говорит нам, что это: n ((n / r) -1 + (r-1) p) где r – количество классов, а p – количество общедоступных методов для каждого класса. Это даст нашей двухклассовой системе MPE 499 000. Таким образом, максимальная потенциальная стоимость изменения в этой системе двух классов уже значительно ниже, чем у неинкапсулированной системы.
Допустим, вы разбиваете свою систему на 3 класса, каждый из которых имеет 333 класса (ну, у каждого будет 334), и каждый из них имеет 50 общедоступных методов. Что такое MPE? Используя вышеприведенное уравнение, MPE будет примерно 482 000.
Если система разбита на 4 класса по 250 методов, MPE будет 449 000.
Если может показаться, что увеличение количества классов в нашей системе всегда будет уменьшать его MPE, но это не так. Теория инкапсуляции показывает, что количество классов, в которые система должна быть разложена, чтобы минимизировать MPE: r = sqrt (n / p), что для нашей системы фактически 4. Система с 6 классами, например, имела бы MPE 465 666.
Принцип бремена принимает две формы.
Сильная форма утверждает, что бремя преобразования коллекции сущностей зависит от количества преобразованных объектов. Слабая форма утверждает, что максимальное потенциальное бремя преобразования совокупности сущностей является функцией максимального числа потенциальных преобразований.
Несколько подробнее, бремя создания или модификации любой программной системы зависит от количества созданных или модифицированных программных единиц.
Программные единицы, которые зависят от конкретного модифицированного программного блока, имеют более высокую вероятность воздействия, чем программные единицы, которые не зависят от модифицированного программного блока.
Максимальное потенциальное бремя, которое может наложить модифицированный программный блок, – это воздействие всех программных единиц, которые зависят от него.
Таким образом, сокращение зависимостей от модифицированного программного модуля снижает вероятность того, что его обновление повлияет на другие программные единицы, и таким образом уменьшит максимальную потенциальную нагрузку, которую может наложить этот программный блок.
Уменьшение максимального потенциального количества зависимостей между всеми программными единицами в системе, следовательно, снижает вероятность того, что воздействие на конкретный программный блок приведет к обновлению других программных единиц и, таким образом, уменьшит максимальную потенциальную нагрузку на все обновления.
Таким образом, инкапсуляция является краеугольным камнем объектной ориентации, и инкапсуляция помогает нам уменьшить максимальное потенциальное число зависимостей между всеми программными единицами и смягчить слабую форму Принципа Бремена.
Большая система, такая как WordPress, Drupal или XOOPS, использует концепции ООП. Вы можете видеть преимущества их использования там. Повторное использование кода, модульность, ремонтопригодность и расширяемость.
У вас есть возможность изменять части объектов, и это влияет на все приложение; не искать заменять каждое место, которое вы выполняли (и, возможно, его не хватало).
Вы можете использовать объекты целиком, сохраняя очень много копий и склеиваний. Исправление ошибки требует исправления одного объекта, а не 16 страниц кода, которые все делают одно и то же.
Когда вы инкапсулируете логику и «скрываете» реализацию, проще использовать объекты, как для вас, так и для вас через 6 месяцев, когда вы забыли, почему вы что-то сделали, а также для парня или гала-гнезда, который использует ваш код. Например, все, что вы делаете, чтобы перебирать сообщения в WordPress, вызывает функцию. Мне не нужно знать, как это работает, мне нужно только знать, как это назвать.
ООП – это действительно процедурный код, обернутый объектными методами / функциями. Вам все равно нужно знать, как писать достойный линейный код для реализации методов и функций объектов. Это просто упрощает повторное использование, масштабирование, исправление, отладка и сохранение ваших вещей.
Я бы сказал, что есть два основных преимущества:
Повторное использование Я бы не строго квалифицировался как преимущество OO, потому что в чисто процедурной модели интеллектуальная организация библиотеки позволяет повторно использовать код.
С другой стороны, использование множества объектов в PHP приводит к снижению производительности по сравнению с процедурной моделью, поскольку для каждого запроса слишком много накладных расходов на строительство объектов. Нахождение хорошего баланса между процедурным стилем и кодом стиля стиля является обязательным.
Чтобы узнать OO в PHP, я бы порекомендовал попробовать использовать хорошую письменную структуру OO PHP.
Вы можете посмотреть на Zend Framework .
Я также PHP, хотя у меня есть сильный фон ООП, я бы сказал, что лучшая книга об использовании ООП с PHP должна быть PHP 5 Object Patterns and Practice
Одна из лучших вещей, которые я сделал с ООП в PHP, – это генератор классов. В любой данной таблице он будет включать почти те же операции SQL:
Теперь мне больше не нужно писать все эти инструкции SQL, за исключением особых условий. Я не только сократил кодировку до 1 минуты, но и сохранил время от кода отладки.
Поэтому всякий раз, когда есть изменения в структуре таблицы, я просто восстанавливаю класс.
Возможно, вы должны попробовать то же самое, что и для меня и моих клиентов!