@vGrabko99
html, css, js, php, golang, mysql

Стоит ли использовать ооп?

Добрый день. Прошелся я по интернету и везде пишут что ООП надо использовать везде где только можно (как по мне разобраться в ООП лапше сложнее чем в функциональной )
И наткнулся я на два приличный источника. Первый это вк (они не используют ооп и говорят что он медленный) и второй источник это phpclub.ru где в статье говорилось что пхп изначально небыл задуман как обьектно ореентированый язык и по этому лудьше писать в функциональном стиле. Все фуекции розбить по назначению и написать в разные файлы. Тем самым построить АПИ для своего приложения. К примеру функции
UserCreate , UserAuth, UserBaned должны быть в файле user.php, а функции ChatNewRoom, ChatNewMessage, ChatDeleteMessage в файле chat.php

Как по мне по второй вариант красивие что ли. Но а как будет правильно если проектом знимаюсь в одиночку?

phpclub.ru/detail/article/phpmistake_2#11

P.S
В ООП кое как розбираюсь. И писал пару робот на нём сильной разницы в скорости между ооп и не ооп проэктами не замечал.
  • Вопрос задан
  • 2324 просмотра
Решения вопроса 4
index0h
@index0h
PHP, Golang. https://github.com/index0h
То, что легче без ооп - безусловно, для скрипта на 100 строк, это будет лишним.

В остальном - однозначно нужно.
ООП дает вам понятие "сущностей данных", как минимум. Можно конечно обмазываться массивами, но в этом случае лучше не используйте в лексиконе слово "безопасность".
ООП дает разграничение обязанностей. Можно конечно нагородить 1кк функций и сварганить на их основе вермишельку, когда выльете пару ведер крови из глаз - вспомните мои слова.
ООП дает заменяемость кода по интерфейсу (Полиморфизм), как следствие - возможность варьировать логику, без миллиона switch-case и сложных условий.
ООП дает сокрытие данных (Инкапсуляция). Если переменную можно изменить в любом месте проекта (глобальную например) - она будет где-то изменена, вы об этом можете не узнать (или попросту забыть), как следствие ваш код будет работать не предсказуемо.
ООП дает возможность расширять функционал порождаемых сущностей (Наследование), как следствие - DRY.

То, что Виталий Пухов написал не верно. Легко !== правильно, удобно, человеко-понятно, тестируемо, надежно. Легко как правило писать говно. Фраза "работает же" как правило значит: "да, я понимаю, что оно хреновое, но лучше не могу".

И писал пару робот на нём сильной разницы в скорости между ооп и не ооп проэктами не замечал.

Вы не туда смотрите)). Производительность на stateless языке... В общем посмотрите на компилируемые))

* Про vk вы правильно сказали, но забыли 2 важных нюанса: он писался, когда ООП в php особо не было; у них свой KPHP))
* Для сравнения у facebook тоже свой php: hhvm, но он очень даже объектный.
Ответ написан
ImmortalCAT
@ImmortalCAT
C# loving
объектно - ориентированное программирование
из этого объектное что? -> программирование
ориентированное что? -> программирование
может ли программирование быть просто программированием :? - > Да
бананово-лимонадный коктейль может быть просто коктейлем ? - да
ООП просто общий концепт при реализации решения - проекта
Ответ написан
Neuroware
@Neuroware
Программист в свободное от работы время
Писать нужно так как будет удобней, нет смысла заморачиваться только потому что это "модно". ООП это хорошо и даже очень во многих задачах, но не во всех он вообще имеет смысл. Если ваше решение без ООП работает и его удобно отлаживат и поддерживать, то это значит что ООП там просто не нужен.
Ответ написан
Тостер, ну почему ты не сохраняешь где-нибудь в local storage сообщения, которые не дописаны? Ааааа! В общем, написал, закрыл вкладку, пишу снова.

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

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

Императивная программа состоит из инструкций, которые что-то меняют в памяти. Если смотреть с минимальным зумом, то много инструкций - это функция. А много функций - это модуль. С точки зрения инженерии ПО важно программе быть максимально модульной, максимально DRY, легко изменяемой, эффективно решающей задачи поставленные и еще много чего. Так вот, кажется, у нас все есть, растащил по директориям кучу файлов, функции/модули/область видимости, но этого не хватит, ведь есть же еще типы, а их надо передавать туда-сюда, обрабатывать. Есть алгоритмы, которым глубоко фиолетово, что обрабатывать, будь то массив, словарь, список, дерево или даже генератор (люблю питон @ пиарю где могу). Кстати говоря, тут можно задуматься о сути итераторов, но это оффтопик.

Во времена популярности ассемблера типов "еще не было". И это вызывало проблемы: множество рутины, множество кода, возможность прострелить себе регистр и так далее. Во времена C были примитивные типы и даже структуры, которые могли хранить данные и указатели на данные. Но все еще как-то неудобно, множество низкоуровневых действий. Нет даже строк, представлять их в виде массива - не слишком удобно, гораздо лучше иметь что-то вроде черного ящика. Где-то в те же времена уже было ясно, что нужно иметь еще более абстрактные типы, которые могут хранить контекст, иметь свои функции (методы), инициализироваться, деинициализироваться. В общем, нужно создавать типы "высокой абстракции", а еще уметь их модифицировать, расширять, комбинировать. И лучше еще с памятью явно не работать. А еще чуть позже популяризовались языки с динамической типизацией, где стало можно не заботиться о типах совсем. Мне даже кажется, что тут уместно сказать, что типов будто "уже не стало". Все есть контейнеры со своей областью видимости. Правда, все это медленно, особенно, если учесть, что динамическая типизация очень любит интерпретацию или динамическую компиляцию. Чем выше уровень, тем все тормознее.

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

С ООП теперь все удобно. Кроме модулей и функций есть сложные типы (классы), которые можно свободно создавать, наследовать, регулировать область видимости, заменять методы, использовать интерфейсы, "строить модули внутри модулей", не использовать глобальные переменные, внедрять зависимости, не дублировать код. В языках, реализующих неклассическое ООП, существует еще больше свободы. Можно использовать миксины направо-налево, классы являются объектами, а где-то и классов нет, потому что есть объект и с ним и так все хорошо))

Это все особо важно и нужно в прикладных задачах, где обрабатываются разные данные, выводятся в разных видах или где есть интерфейс пользователя с множеством однотипных элементов. Практически всегда там возникает ситуация, когда нужно определить множество похожих объектов, сделать удобное API, использовать и расширять стороннюю библиотеку. Кроме того, существует множество паттернов, которые можно переносить откуда угодно куда угодно, не думая при этом. В вебе, с учетом того, что 95% приложений крутятся вокруг MVC и его вариаций, ООП очень даже кстати: модельки - это однотипные объекты из однотипных полей, имеющие в себе какую-то логику (свои функции/методы), контроллеры - однотипные объекты (получение данных/параметров запроса, выдача необходимого ответа в нужном виде). Если взять любой фреймворк, то там реализовано множество модулей, которые что-то реализуют: ORM, роутинг, кэш, сессии, request-объекты, response-объекты, какие-нибудь карты сайта, админки, модельки для юзеров, что-нибудь для работы со статикой, формы, локализация... Если нужно что-то расширить, то достаточно посмотреть на API, отнаследоваться, реализовать/заменить метод.

Наверное, нужны какие-то примеры. Вот представьте, что пишете простой сайт, который должен отдавать готовый HTML. Но кроме этого сайт модный, поэтому он полностью ajax (html5 history api), никаких перезагрузок, только первая загрузка страницы, которая выгружает и фронт и стили и отрендеренную страничку, а потом дергаются нужные данные для других страниц (в json, туда кладется отрендеренная часть и еще какие-нибудь важные данные) с бэкенда. Оговорюсь, что это не SPA, а именно full ajax сайт, который все-таки еще рендерится на сервере в каком-нибудь серверном фреймворке. И ваш бэкенд должен отдавать, соответственно, 2 варианта страниц: обычную (как при прямом заходе по ссылке, это и для пользователя и для бота) и json-вариант для других страниц (это уже только для пользователя, соответственно). Вы создаете крутой контроллер, который в зависимости от параметров в GET, либо в зависимости от заголовка рендерит то json, то html. А дальше наследуетесь от этого контроллера и совсем не заботитесь о том, что у вас отдает конкретный контроллер: переопределяете метод с контекстом и отдаете в нем нужные данные, а уж что с ними станет в шаблоне или как их обработает фронтенд, получив из json, - без разницы. Нужно сделать только ajax-контроллер? У вас для него есть класс, осталось опять же только отнаследоваться. Нужно отдавать SEO-заголовки? Можно сделать миксин для контроллера и миксин для модельки и снова переопределить только один метод а-ля get_meta_title и все. Ну, понятное дело, я тут упустил мелкие подробности и все это актуально больше для языка вроде python и подобных (уж на чем пишу), но вот пример ООП-задач.

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

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

Вообще, примеров очень много, они повсюду, особенно, в вебе. Если в таких прикладных задачах не использовать ООП, то я даже не представляю, как тестировать этот код. Как его поддерживать, меняя логику? А как менять компоненты? Как быть DRY? Тут я, кстати, вспомнил про то, что вот, например, есть в C структуры. Это что-то вроде урезанного класса и на самом деле можно реализовать многие штуки с ними, писать отличный код, но он просто будет сложнее в поддержке и по скорости разработки будет очень далеко позади. Ядро линухи выглядит очень красиво и совсем там не лапша. Однажды фиксил драйвер, чтобы заработал 5ггц вай-фай, так вот он был красив и строг внутри. Кстати, в Go классы реализованы в виде структур, но я не смогу подробнее рассказать об этом, т.к. не смотрел этот язык. ООП - это не какая-то супер фича, а это всего лишь подход. Языки же добавляют синтаксический сахар, реализуют классическое ООП (java/c#/c++/etc) или же неклассическое (python, js, etc).

Кроме ООП-парадигмы и процедурной парадигмы есть еще, например, функциональная. Но это отдельная совсем тема. В мультипарадигменных языках можно писать по-разному. Если что-то удобно представляется в виде цепочки функций, выглядит так, как будто нет побочного эффекта или его легко изолировать, то нет стоит городить классы или процедурный ад. Тем более в языках, которые близки к ФП, обычно полно встроенных функций, можно объявлять анонимные функции, почему бы этим не пользоваться. Ну или, например, у вас получился какой-то модуль, в котором не нужна ни инициализация, ни контекст ему не нужен, все выглядит как просто 4 связанные функции, то зачем здесь нужно ООП? Хотя если что-то из этого можно кастомизировать, а вы чувствуете, что это понадобится, т.к. есть объекты, которые будут расширять функциональность, то стоит задуматься. Главное не оверинжинирить.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
vt4a2h
@vt4a2h
Senior software engineer (C++/Qt/boost)
Русский язык сначала освойте. PHP вам рановато.
Ответ написан
@heartdevil
плыву как воздушный шарик
Я советую вам как можно скорее переходить на ООП и все делать на ООП.

Если раньше было так, что все писали функциями, а исключениями было ООП, то теперь все надо делать на ООП и только в исключительных ситуациях функции.

А почему я вам советую, потому что в ООП не так просто разобраться. Там уйма тонкостей. Поэтому чем раньше вы начнете, тем больше опыта наберетесь, когда будете работать на серьезными проектами. Если вы не гений, то у вас не один год уйдет, на освоение в достаточной степени (зависит, конечно, от интенсивности работы).

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

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

Войти через центр авторизации
Похожие вопросы
Reliable systems Саратов
от 150 000 до 250 000 ₽
Eyeconweb Екатеринбург
от 120 000 до 200 000 ₽
Bitrix Калининград
от 100 000 до 250 000 ₽