@sarathorn
php программист, веб-дизайнер, коллекционер

Вопрос про ООП, как использовать?

Дамы и господа, у меня возникла проблемка.

Я начал изучать PHP в далёкие бородатые годы, проще говоря, php 5 ещё только появлялся. Я учился по литературе, которая писалась по большей части для php 3 и 4. И сейчас я столкнулся с интересной проблемой.

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

Вот, например, надо сделать простейшую фотогалерею. Есть тупо список галерей без вложенности, в каждой галереи неограниченное число фоток с описаниями. Как правильно запилить всё это на ООП? Если я принимаю галерею за объект, как поступать с фотками? Для каждой фотки делать $image=new image($айди_фотки); ??? Или использовать вариант в духе $gallery->getPhoto($айди_фотки); ?

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

95% кода я пишу для личных нужд. Вернее, с этим кодом никто, кроме меня не работает. Есть простая CMS для клиентских сайтов, есть пара веб-сервисов, которые поддерживаются только мною.

Я чувствую себя вне тусовки, ведь я не использую ООП. А не использую... ибо не до конца понимаю как и зачем. Если я пишу блог, мне нужно весь блог принимать за объект, а посты вытаскивать по принципу $blog->getPost() или $post->content()? А что делать с комментариями? По сути, каждый коммент - это отдельный объект. Я усложняю жизнь?

Назовите меня говнокодером, но
$post=BLOG::getPost($айди_поста);
echo $post['content'];
$comments=BLOG::getComments($айди_поста);
echo $comments;

это работает. И я отлично понимаю как. Пример очень упрощён, но, думаю, суть вы поняли.

UPD:
Как я понял, если меня занесёт в разработку очень навороченных проектов, где работают более двух программистов, тогда без ООП вообще никуда. Если я пишу что-то несложное, если что-то редкоизменяемое, или если что-то сложное, но в одиночку, то стоит писать так, как удобно, а не так "как положено". Ведь самое главное это результат, а не способ его достижения (при условии, что мой код работает без ошибок и не нагружает систему до опупения)
  • Вопрос задан
  • 2845 просмотров
Решения вопроса 4
ThunderCat
@ThunderCat Куратор тега PHP
{PHP, MySql, HTML, JS, CSS} developer
Вот, например, надо сделать простейшую фотогалерею.
На вашем примере, что бы было понятно на пальцах, заранее прошу прощения у присутствующих за примитивизм. В данном случае у вас будет коллекция объектов, которая тоже объект, это как массивы, если примитизировать понятия до упора, одни могут быть вложены в другие. Делаете допустим так:
$image= new Image(); //создаем пустой объект имаж, чтобы иметь его настройки(таблица, поля...)
$gallery = new Collection ($image); //создаем новую коллекцию объектов типа имаж, пока пустую.
$gallery->getCollectionByField(array("galleryid"=>"64")); // инициализируем из базы, используя
// ид галереи, теперь в гэлери одной строчкой мы загрузили все картинки в свойство (например),
// $gallery->collection  и можем к ним обращаться как к элементам массива, и в свойстве
// $gallery->collection[1] будет объект типа $image. Как вариант реализации.

Куча кода остается в объекте, для вас это "черный ящик", видны только входы и выходы, все что внутри скрыто, но работает как надо, т.к. разбито на методы и отлажено по кусочкам.

Что касается статики - как говорится в любом нормальном источнике - статики нужно избегать по максимуму, на это есть несколько причин:
- статика загружает оперативку, т.е. статические объекты создаются всегда, не зависимо от необходимости их использования
- статика плохо поддается тестированию, не всегда, но часто, т.к. глобальная область видимости приносит проблемы пересечения зон ответственности методов, часто это нарушает SOLID, особенно если тыкать статику везде. Почитайте, посмотрите как должен выглядеть нормальный код в объектах - вам понравится.

ps:
ваш код - почему бы не писать так:
$post=BLOG::getPost($айди_поста);
// меняем 
$post = new Post($айди_поста);

echo $post['content'];
// меняем 
echo $post->content; // не обязательно так, может вот так:
echo $post->getContent(); // тогда при выводе можно будет сделать какую-то предварительную обработку, 
//заменить тэги, еще что-то...

$comments=BLOG::getComments($айди_поста);
// меняем
$comments = new Comments($post);
echo $comments->getTree(); // хотя тут скорее всего от вьюшки зависит, я бы тут возвращал не 
// строку, а массив для итератора, это правильнее для разделения на мвц, мухи отдельно - 
// котлеты отдельно, в смысле код и хтмл.
Ответ написан
Комментировать
iwqn
@iwqn
Программист-самоучка
Мне в своё время объяснили - ООП нужен в сложных проектах, которые поддерживают и кодят много людей. ООП позволяет привести код к определенной системе и при очень больших объемах кода помогает избежать повторений.

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

Тут каждому своё - если что-то простое писать то ООП в PHP вовсе не нужен, на мой взгляд.

Интересно будет послушать мнения
Ответ написан
Комментировать
Epsiloncool
@Epsiloncool
Программер, веб-девелопер, гейм-девелопер
ООП по сути - это синтаксический "сахар" и уровень абстракции. То есть вы можете сделать очень большой проект совсем без ООП, он будет работать. Но сопровождать его будет крайне тяжело, так же тяжело и дорабатывать и тем более что-то там исправлять.

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

Объект в ООП - это замкнутая в себе законченная сущность, с которой можно работать дёргая за рычажки - методы. Это позволяет абстрагироваться от того, что происходит внутри объекта. Удобно, например, в случае с вашей галереей, представить одиночное изображение как объект и получать из него всякие свойства, такие как imageUrl (путь к изображению), запускать ресайз изображения (resizeImage) и всё такое прочее, совершенно не думая о том, как это всё внутри сделано.

Аналогично, если всю галерею представить как объект, можно работать с ней через её методы, например, получить список всех изображений через getAllImages(), выбрать только популярные через getPopularImages() или реализовать более мощную функцию с возможностью отбора по параметрам getImages($params), добавление новых изображений через addImage($img) (при этом в коде галереи будет содержаться весь код, необходимый для сохранения изображения в БД и на диске, формирования статической ссылки и всё такое прочее.

Можно создать несколько галерей простым вызовом new MyGallery() и быть 100% уверенным в том, что галереи никак не будут мешать друг другу в работе.

Научитесь думать в ООП-стиле и ваша жизнь в корне изменится.
Ответ написан
Комментировать
@red-barbarian
Дело не в том какая парадигма лучше/хуже. Дело в том какая ближе к вашему мышлению и моделировании области которую вы описываете. Если вы мыслите процедурами, то ооп в коде будет притянута за уши. Если код понятен, легко читается, то этого достаточно.
В качестве развития можно почитать что-то из оо проектирования.
Процедурность и ООП это два разных подхода к пониманию системы. (Это не ключевые слова в синтаксисе. ). Разные подходы к решениям проблем всегда полезны. Хотя не напрямую.
Т.е. умейте много, применяйте что эффективно для конкретного случая.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 6
saboteur_kiev
@saboteur_kiev
software engineer
Подход процедурного программирования - во главе стоят функции и алгоритмы.

Во главе ООП стоят данные.
У вас есть данные, простой int или сложная структура в виде учетной записи (имя юзера, пароль, емайл, полное имя, etc)
Вот эти данные вы упаковываете в класс, к ним добавляете методы, которые работают именно с этими данными.

Это позволяет вам оперировать данными в виде класса. Вы точно знаете, что данные, в том формате, в котором они находятся и обрабатываются внутри класса, НИГДЕ больше не используются, кроме как в этом классе.
Если другому классу нужны данные вашего класса - для этого создается метод.

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

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

Это в принципе основная суть ООП.
Все дальнейшее - наследования, полиморфизм и так далее - попытка сделать ООП гибче, ибо встречаются ситуации...
Ответ написан
Комментировать
@bioroot
Добавлю свои пять копеек. Мне в своё время очень помогла идея интерфейсов, хотя они и довольно умеренно прижились в php и в основном на низком уровне. В вашем примере вы могли бы вынести обработку комментариев в отдельный метод, который требовал бы от объекта-аргумента имплементить интерфейс, требующий наличия метода getComments. Дальше этот метод уже сам строит по комментариям дерево. Потом вы упаковываете этот метод в файл и когда вам нужно дерево комментариев к любой сущности (не только блогу, а к фотогалерее, новости и т.п.) дёргаете этот волшебный метод. При условии что вы соблюдаете некие свои собственные соглашения о формате комментариев всё будет работать само собой. А если вы подсунете сущность, которая не имеет метода getComments, то сразу узнаете об этом.

Конкретный пример конечно высосан из пальца, но в системах с количеством сущностей более трёх интерфейсы здорово помогают. Вы можете ещё на этапе проектирования заложить требования к входящим данным для реализации каждого конкретного куска логики. А бонусом получите то, что этот кусок логики будет в дальнейшем корректно работать с любыми данными, которые удовлетворяют требованиям.
Ответ написан
Комментировать
@ForbsmC
Love this world..
Ну. Я и сам то только изучаю ООП, но мне ООП в пыхе понравился больше, чем процедурное. Код выглядит на много меньше, и лаконичнее.
Ответ написан
Комментировать
alexchin
@alexchin
Лучшие практики разработки показывают что использование фреймворков типа GodeIgniter, YII, Laravel и т.д. (чтобы никого не обижать) оправданы и фреймворки берут на себя большинство рутинной работы - безопасность, маршрутизация, кэширование, ORM и т.д. Однако фреймворки разработаны в идеальном объектном мире, где ООП используется на полную катушку. Где же место вашим объектам в этом мире? Сконцентрируйтесь на вашей предметной области! Если это блок с постами и комментариями, значит создайте объектную модель как показано выше. Фреймворк, кстати, может помочь, например реализовать материализацию объектов из системы хранения или удобную основу для иерархии классов. В сложных проектах также вполне применим DDD. Также развитию идей ООП способствует чистый код..
Ответ написан
Комментировать
@izometric
Дле меня суть ООП раскрылась после изучения YII2.
Ответ написан
Neznayka1979
@Neznayka1979
Интересы - IT, психология...
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы