Я упустил смысл объектно-ориентированного программирования?

Недавно я взял на себя попытку освоить ОО-программирование. Прошло около 3 месяцев с тех пор, как я начал, но я думаю, что я мог упустить момент, потому что я, кажется, предпочитаю статические методы (которые мне кажутся "более простыми").

пример

Вот как выглядит типичный запрос к БД в моем коде.

$bindings = array(':name'=>$articleName);

Db::query('SELECT id, name, title, image, content FROM ' . CONFIG_MYSQL_TABLE_PREFIX . 'articles WHERE name = :name LIMIT 1', $bindings);

А вот как я изменяю размеры / кадрирую / кэширую изображения

$image = Img::thumbnail($imagePath, 200);

$imgHtml = '<img alt="' . $this->getTitle() . '" src="' . '' . $image['src'] . '" width="' . $image['width'] . '" height="' . $image['height'] . '" />';

Оба статических метода используют одноэлементный шаблон. Первый создает один объект PDO, а второй создает один класс ImageResize, который я нашел в коде Google.

Должны ли они быть двумя объектами, если я действительно хотел бы назвать это объектно-ориентированным программированием? т.е.

$db = new Db();

$image = new Image($src, $width, $height);

За каждый раз, когда я их использую? Я читал, что синглтоны тоже плохая идея, если только они не используются для записи в файл. Но разве синглтон не подходит для одного соединения с БД, которое открывается, когда необходимо, и закрывается только после того, как оно было использовано и завершено?

Мой вопрос: я все еще застрял в процедурном мышлении, и если да, то, что я делаю, считается плохой практикой? Как я могу погрузиться в правильные ОО-шаблоны мышления?

Обновить

Спасибо за ответы. Я нахожу, что оригинальные методы, которые я делаю, проще, так как я должен набирать меньше кода и позволить статическим методам беспокоиться о мелочах реализации.

Я посмотрю на другой язык, чтобы получить полное представление о OO, хотя этот язык сам по себе будет другим вопросом.

6 ответов

Решение

Ну, imho PHP - плохой пример для этого, потому что PHP не является объектно-ориентированным. Да, у него есть объекты. Да, они поддерживают наследование и все эти принципы ОО. Поддерживает объекты. Есть разница

Я говорю это, потому что PHP по умолчанию не существует в состоянии между запросами. Каждый отдельный HTTP-запрос полностью воссоздает среду PHP с нуля (что является достаточно дешевым), то есть между запросами не сохраняется статических данных. Вы могли бы сказать "как насчет данных сессии?" (и, возможно, добавьте "ха!"), но это не постоянные данные в смысле PHP. Они (как правило) хранятся в файловой системе и хранятся в файле cookie, отправляемом клиентом.

Почему я упоминаю эти две вещи?

Потому что "глобальная" область не похожа на глобальную область в C, Java, C++ или этих других языках, потому что они имеют тенденцию сохраняться между запросами. PHP больше похож на модель программирования CGI из 90-х (что не случайно, потому что именно там она и возникла).

Таким образом, ваши объекты не являются действительно глобальными: они просто видны всем частям кода, обслуживающим текущий запрос.

Для меня это далеко не так плохо. На самом деле, я часто нахожу это вполне приемлемым. Иногда это все необходимо (например, в обратном вызове preg_replace_callback, если вы хотите отправить информацию обратно вызывающей стороне или передать состояние обратного вызова без выполнения хаков eval()/create_function()).

И смысл в том, что PHP не является объектно-ориентированным, заключается в том, что даже в PHP 5 функции OO все еще несколько "привязаны", а это означает, что вы можете с радостью кодировать и кодировать в PHP без их использования. Это отличается, скажем, от Java, где вы должны создать класс, даже если все, что вы делаете, это пишите в нем кучу статических методов.

Так что если вы хотите изучать ОО, честно говоря, я бы не стал делать это на PHP. PHP хорош для многих вещей, но он разработан, чтобы иметь жизненный цикл HTTP-запроса (да, я знаю, что вы можете запустить его из командной строки, но это не то, что делает подавляющее большинство пользователей), и он довольно хорош в работе, для которой он предназначен,

Лучший способ понять объектно-ориентированное программирование - думать о объектах, передающих сообщения друг другу, а не об объектах, вызывающих функции. у меня был этот момент "эврика", когда я изучал Smalltalk.

Существуют принципы, которые применяются к ООП, такие как принцип "не спрашивай" и другие. используйте вашу любимую поисковую систему для поиска этих принципов.

На мой взгляд, обилие статических методов является признаком застревания в процедурном мышлении. Конечно, есть сценарии, в которых они действительно имеют смысл, но если в вашем коде больше статических методов, чем методов экземпляра, я бы сказал, что вы не делаете вещи OO-способом.

Вам может показаться, что легче понять идеи более твердо на языке, который поддерживает ООП в качестве основной парадигмы... не то, что вы не можете сделать это на php, perl или чем-то другом, просто это не так просто, потому что есть немного ограждений и поощрения

кроме языков, может также случиться так, что виды вещей, которые вы делаете сейчас, действительно не требуют ООП; если так, не парься, играй с ООП на других вещах.

ОО помогает в управлении государством в императивной среде.

Чтобы взять два примера, которые вы приводите, во-первых, Db::query, за этим я предполагаю, что это некое соединение с базой данных, которое является статическим методом, это означает, что везде в разрабатываемом вами программном обеспечении это либо:

  • Противоборствующие замки
  • Имеет проблемы с многопоточностью
  • Повторное подключение к базе данных для каждой транзакции

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

Имея Db в качестве объекта, вы даете себе больше контроля над тем, как система может развиваться.

Аналогично генерации миниатюр, если вы хотите, чтобы система кэшировала миниатюры и т. Д., Имея объект, имеющий дело с ними, это дает вам лучший контроль над их жизненным циклом и тем, как они используются.

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

Как и во всем, это баланс, и только контекст, в котором вы работаете, определяет ценность такого рода вещей, так как вы новичок в OO. Я постараюсь немного (год или два) и посмотрю, что на самом деле, кажется, дает вам преимущества. когда опыт подсказывает вам, что следование таким принципам в вашем контексте мало что дает, тогда, может быть, перестаньте им следовать, просто будьте осторожны, когда ваш контекст изменится.

Я изо всех сил пытаюсь представить худший способ изучения ОО, чем реляционные базы данных в PHP. Несколько других упомянули проблемы с PHP. Я укажу вам статью нашего уважаемого основателя, в которой обсуждается, почему объекты и отношения не смешиваются:

Объектно-реляционное картирование - Вьетнам компьютерных наук

Вы бы лучше попробовали что-то вроде программирования GUI на Python. Я рекомендую Python, потому что он имеет хорошую поддержку, но не требует ОО, поэтому вы с меньшей вероятностью увидите, что ОО используется в тех случаях, когда это неуместно. Я рекомендую программирование GUI, потому что программирование GUI почти невозможно без методов OO.

Я не использую ОО ради его использования. Если мне нужно написать небольшую программу, я предпочитаю процедурный подход. Использование ОО в более мелких вещах может только усложнить проблему, или даже если этого не произойдет, это не будет означать преимущества по сравнению с процедурным подходом в любом случае.

Но, если мы рассмотрим более серьезную проблему, связанную с множеством сущностей, обязательно создадим хорошую диаграмму классов и дизайн, чтобы реализовать и использовать реальную силу ОО. Используйте OO всякий раз, когда это необходимо; просто не применяйте ОО в небольших задачах ради этого.

Другие вопросы по тегам