Pull to refresh

Comments 325

Кстати есть такой способ замены грядущих в PHP 5.3+ неймспейсов. Только, к счастью, на этом ООП не заканчивается :)
UFO landed and left these words here
есть игра.
в игре есть юниты.
вы предлагете код копировать, вместо наследования?
На самом деле любой, кто хорошо знает C++, знает, как вся эта объектная модель работает, и как просто её реализовать вручную, голыми функциями и структурами, на чистом C.  Можно ничего и не копировать.  Это распространяется и на PHP.  Но такое извращение — для совсем уж ограниченных систем; PHP к таким не относится, но игры на нём тоже обычно не пишут.
много-много (список: mmorpg.rpgland.ru) онлайновых игрушек написано на PHP
Интересно - а он что все классы потом в один файл склеивал
И что-же на самом деле было там ДО НЕГО?
UFO landed and left these words here
«идиотский вопрос: «чем классы лучше?»
— Вы, наверное, не правильно поняли… Автор как раз-то и не сравнивал их по «лучшести».

«В то же время ООП вытекает напрямую из процедурного подхода.»
— Не согласен. ООП вытекает из объектного подхода, последний, в свою очередь,— из «ориентации на данные» в процедурном программировании.

Ваше определение класса мне не понятно. Класс — описание объектов,— всё!

Вывод: «Пришедший на собеседование не должен допускаться к разработкам, при таком уровне». Если кто-то говорит что ООП, это: «револьция», «развитие процедурного программирования», то он тут же выдает свое дилетантство в этой сфере. Процедурное программирование не умрет, покуда не умрет императивное.

Автору спасибо.
UFO landed and left these words here
1) Лучше чем что?! Это был, как я понимаю, не идиотский, а провокационный вопрос. Причем, сравнивалось группирование функций: в одном файле или в одном классе. Что к ООП никакого отношения не имеет вообще. А вы автору безпардонно приписываете сравнение применимости ПП и ООП в неопределенной задаче.

2) Не получается :). Поясните, пожалуйста, как это у вас получилось.

3) Если вас такое утверждение обезкуразило, то специально для вас исправлюсь: «Класс — декларативная конструкция для описания свойств (в общем смысле, в т. ч. и методов) объектов, порождаемых как экземпляры данного класса» :)
Мне первый вариант больше понравился.

«Класс — по большому счету, лишь некоторая мета-структура, позволяющая описать процедурный код в отрыве от других частей программы.»
— Смысл этого набора слов я не уловил. Взять хотя бы «мета-структура», т. е. «структура структуры». Как это? Агрегация одной структурой другой? Я не могу этого понять :) «В то же время ООП вытекает напрямую из процедурного подхода.» — можно пояснить как это происходит? «описать процедурный код в отрыве от других частей программы» — могу посоветовать модули или пространства имен :) К классам лучше не подходите :). Оставьте их людям, нуждающимся в описании данных.

«я где-нибудь сказал о том, что процедурное программирование на последнем издыхании?»
— а я где-нибуть сказал что вы это сказали? :)

«Прежде чем «наезжать» на других» — а вот тут, тебе надо бы обосновать, где и на кого я наехал? (Цитата.)

Садитесь, sandycat, вы заблудились…
UFO landed and left these words here
UFO landed and left these words here
Можно я признаюсь в своем неведении?

Кто нибудь внятно ответьте: "В чём приемущество ООП перед процедурным подходом?"

Буду очень благодарен если дадите ссылки на материалы "ООП для дегенератов", но только чтобы на примерах было видно что РЕАЛЬНО дает ООП.

PS: либо я что то кардинально не понимаю в жизни, либо еще более кардинально в ООП
Неужели нельзя реализовать связь объектов с БД если я использую процедурное программирование?

(Объекты как сущности у меня всегда присутствуют. Только без классов и прочего.)
Хэш-массивы?
Дело в том, что объект содержит данные и методы для управления ими.
У вас есть рука, вы должны ей двигать, а не какой-то дядя за вас.
по сути какая разница, методы управления лежат внутри данных либо рядом?
Никакой. И то и другое - OOP. К примеру CLOS так устроен.
Если они рядом, то вам самому надо о них заботиться. А ООП инкапсулирует реализацию и данные. Он неявно от метода к методу может передовать состояние системы объектов. Вам важен только интерфейс. Наверное нет такого примера, чтобы чтото нельзя было сделать процедурно, но можно лишь с использованием ООП. Но часто с ООП намного проще разработчику использовать написанные алгоритмы.
Для начала тут нужен хороший опытный руководитель. Книжек аля "ООП для дегенератов" не встречал, а вот дегенератов в ООП множество.
У меня был замечательный опытный руководитель - апологет ООП, XML и международных стандартов, но даже он не смог мне объяснить РЕАЛЬНОЕ преимущество.
РЕАЛЬНЫХ преимуществ у ложки перед вилкой нет. Просто суп удобнее есть ложкой, а пельмени - вилкой. И никто вам ничего не объяснит и не докажет, если вы сами не хотите принимать что-то новое.
я ем пельмени ложкой, т.к. люблю их с бульёном :)
UFO landed and left these words here
У вас ник с ошибкой написан :)
UFO landed and left these words here
UFO landed and left these words here
UFO landed and left these words here
давайте жить дружно (с) Леопольд. кот.
выходи, подлый трус!
у ложки перед вилкой одно РЕАЛЬНОЕ преимущество - жидкое не проливается
и как следствие - класс задач которые вилкой нельзя решить "кушать суп"
Вы не поняли метафору. Любой софт можно написать на ASM, Бэйсике или, если угодно, на Хаскеле, но никто этого не делает, потому что это глупо. Каждое решение подходит для своих задач. Для написания и поддержки больших проектов удобнее использовать ООП.
поддерживаю. особенно, в связи со сложившейся ситуацией пихать ООП в любое приглянувшееся место. это как PostresSQL использовать для сайта-визитки в одну страницу ).

есть у ООП, правда, два самых главных достоинства, из-за которых это и происходит - возможность повторного использования кода и простота в отслеживании структуры, что позволяет легко работать командой.
У вилки перед ложкой одно РЕАЛЬНОЕ преимущество - можно зафиксировать еду и как следствие - класс задач которые ложкой нельзя решить "кушать спагетти"
Именно этим отличается вилка от ложки.

Вилкой можно есть спагетти(еду которую надо зафиксировать) и нельзя нормально есть суп(жидкие продукты).
Ложкой наоборот.

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

Я действительно не знаю - до меня в свое время не донесли этот момент.
Спагетти правильно кушать, используя одновременно ложку и вилку. Что кстати абсолютно точно переносится на применение ООП. Бывает удобно иметь часть кода объектно-ориентированным, а часть в библиотеке в виде функций ;)
Вообще-то спагетти можно есть и вилкой, ложка для удобства.
Можно-то можно, а правильней с ложкой. Если вы конечно не итальянец...
Это где такое правило написано? Не видел ни одного итальянца, который применил бы ложку к спагетти...
Спагетти, или макароны - соломка, излюбленное блюдо темпераментных итальянцев, пользуются популярностью и у нас в России. Но, к сожалению, многие россияне забывают, что это самостоятельное блюдо, а не гарнир к мясу. Спагетти подают в глубоких тарелках. Существует несколько способов употребления этого блюда, мы же рассмотрим два, наиболее распространенные — классический и "итальянский".

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

Согласно классическому способу, спагетти едят столовой ложкой, которую держат в левой руке и столовой вилкой, которую держат в правой. Вилкой поддевают две-три нитки макарон и "вытягивают" их до уровня груди. После этого начинают наматывать, вращая вилку движением "на себя" и одновременно опуская в тарелку. Заканчивают наматывание, почти опустив спагетти в тарелку, — в подставленной ложке, роль которой заключается в том, чтобы спагетти на вилке были отделены от спагетти в тарелке.

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

http://www.google.ru/search?hl=ru&q=%D0%…
Встречал много книжек "ООП для дегенератов", только все они назывались "ООП для профессионалов", "ООП в подлинике" и т.п.
UFO landed and left these words here
Если более общими словами, то "снижение сложности".
Если более правильными словами, то "разделение сущностей".
мне казалось что разделять сущности можно и при процедурном программировании...
Procedural code gets information then makes decisions. Object-oriented code tells objects to do things.
— Alec Sharp

В этом вся разница.
Не соглашусь. Объекты не могут do things, если им не указаны эти сами things. А things и есть суть information. Так что тут на лицо подмена понятий.
Object-oriented code tells oject's procedures to do things with information, stored in object's properties.
Можно, а еще есть "методика общей шины". IMHO ООП лучше тем, что позволяет не беспокоиться о некоторых вещах, которые возлагаются на компилятор. Плохо, ужасно, хорошо и отлично можно писать и с ООП и без него.
я имею ввиду, что инкапсуляция, наследование, полиморфизм, разделение сущностей необходимы для снижения сложности
Просто ремарка — не всякую сложность можно уменьшить. Ту, которая "essential complexity", снизить нельзя; ее можно только переместить в другое место. А вот Accidental complexity уменьшить вполне себе возможно.
оффтопик: ремарка — это примечание автора к своему же тексту. русский язык - это не кунг фу. желательно пользоваться им и без необходимости.
+абстракция. забыли )

книжка для самых маленьких чайников - скать по автору Кодд
для тех, кто не умеет расшифровать письмена с помощью гугля:

абстракция = все элементы программы представляются в виде законченных и выполняющих свою роль объектов, благодаря чему можно четко отследить, что и как делает, наглядно представить взаимосвязи (например, с помощью UML).

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

наследование = возможность создавать "потомка" объекта, который наследует всю или часть структуры, но вносит в нее свои дополнения и изменения. опять же "повторность кода", но на самом деле, все гораздо сложнее - почитайте, к примеру, лекции по Java.

ну и, наконец, полиморфизм - это свойство наследования, которое позволяет использовать указатель на объект-родитель, для указания на объекты-потомки и использовать методы последних. популярно это выглядит так - объект класса Database может быть создан как объект класса MySQL, Interbase, Oracle (которые являются потомками DataBase) и при этом при вызове одной и той же функции connect() в разных случаях будет выполняться код такой функции, реализованный в конкретном классе потомка.

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

... существует Что-то. Этому Что-то свойственно быть Таким-вот или Вот-таким. Это Что-то умеет Делать-так и Делать-эдак.

ООП-терминология для описания самого Что-то, его свойств и умений:
класс - Книга для записи разных сведений о Что-то
инкапсуляция - все что касается Что-то (само Что-то, его свойства и умения) описать в одной Книге
наследование - если есть два разных, но похожих Что-то, то общее они получили от своего родителя Большого Что-то (если два Что-то умеют Делать-так, то это умение они приобрели у Большого Что-то)
полиморфизм - два Что-то умеют Делать-так, но каждый по-разному
ну вот еще из области шуток
http://forum.dklab.ru/viewtopic.php?p=55543#55543

правда здесь нет ответа на вопрос - чем хорошо/плохо ООП
Я бы насчет определения абстракции поспорил. Не совсем это то, о чем вы написали.
ух, ну вы выкопали :)

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

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

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

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

я теперь правильно все объяснил? :)
Да :) Не знал, что это вас так сильно заденет.
В структурном (процедурном) подходе тоже есть инкапсуляции.
Посмотрите на Smalltalk/Ruby и на Seaside/Rails. Ссылы поищите в гугле, он все знает.
спасибо за слово "Seaside"
Немного некорректное сравнение.

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

Основная идея ООП - оперирование объектами. Инкапсуляция, наследование, полиморфизм - это вторично.
Главное что иногда в голове удобно оперировать объектами, а иногда "последовательностями действий"

Тут уж как говорил Карцев: "Выбирай осторожно, но выбирай. Либо вчера большие, но по пять, либо сегодня маленькие, но по три"
>Там где явно выделяются процессы, процедруный подход.

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

Только вот то, о чем ты говорил про ООП, называется объектное программирование. ООП вносит, в сравнении с объектным, декларативность (бОльшую) и нерушимость структуры объектов и их иерархий.
Лично для себя я вижу несколько плюсов ООП:
1. Наглядное представление и структурирование кода.
2. Не возникает проблем с пространством имен. Например, если у вас есть две функции: одна создает файл, другая базу данных, они могут иметь одно и тоже название create($name) и вызыватся соответственно files->create('abc') и db->create('abc'). Опять же если вам надо например проводить операции с двумя серверами баз данных то нужно заводить больше переменных. То есть например Name1, Name2, Table1, Tanle2... А так создается всего два объекта db1 и db2 а все переменные типа name и table определены в них и не возникает путаницы.
3. Код получается более краткий. Например, есть задача добавить одну строку в таблицу и удалить другую (например не с двумя, а со 100). Как это выглядит в процедурном исполнении:
addStringToTable('table_name',$string);
deleteStringFromTable('table_name',$string);
Аналог в ооп не использует везде 'table_name':
db->table='table_name';
db->add_string($string);
db->delete_string($string);
Этот пример просто показывает наглядность кода.
4. Автоматическое подключение файла с классом.
5. Лично мне приятней работать с классами. Их как мне кажется легче использовать повторно. Поэтому, конечно если мне 2+2 нужно посчитать - я делаю функцию, а если нужно с ФС работать то класс. Если это пригодится потом то лучше класс)
1. с процедурами тоже можно
2. $file_pointer=files_create('abc'); $db_pointer=db_create(abc);
3. а по моему все таки так :
db_add_string($db_pointer,$string);
db_delete_string($db_pointer,$string);
4. а что мешает автоматически подключать файл с функциями?
5. почему тогда работа с файлами реализована в виде функций а не классов в большинстве языков?
db_add_string($db_pointer,$string); - сколько здесь использованно аргументов?
db->add_string($string); - а здесь?)
Да банально какая строка короче?)
во втором случае реально тоже два аргумента, первый - ссылка на экземпляр класса просто опускается, его подставляет компилятор.
ну это я так, не cмог промолчать :-)
Это в принципе ясно. Но строка всеже короче) При той же информативности.
Немного обобщим (предположим, что у функции не 1, а N параметров).

Функциональный подход: db_func($db, $param1, … $paramN)

Составляющие:
1. db — псевдонеймспейс
2. func — функция
3. $db — экземпляр сущности
4. $param1 — 1-й параметр

3 + N. $paramN — N-й параметр

Количество составляющих 3 + N.

Объектный подход: $db->func($param1, … $paramN)

Составляющие:
1. $db — экземпляр сущности
2. func — функция
3. $param1 — 1-й параметр

2 + N. $paramN — N-й параметр

Количество составляющих 2 + N.
Оба примера - это объектный подход. То, что вы записали одно и то же разными способами сути не меняет. Собственно классы появились именно как развитие того, что вы назвали "функциональным подходом".
Так дело в том, что ООП - это вовсе не форма записи, это концепция организации кода. Сама форма записи не имеет значения. Равно как и выбор языка. Другое дело, что определенная форма записи, определенный как бы заставляет (или пытается заставлять) следовать принципам ООП, создает для этого подходящие условия.
Я не говорил об ООП, я говорил об объектом подходе к форме записи.

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

Например, используя подобную функциональную форму, будет нелегко реализовать наследование, приватные свойства, виртуальные функции, фабрики и другие интересные вещи.
Смысл один и тот же. Если вы пишете процедурно в таком стиле, значит вам удобнее будет использовать ООП, потому что он для этого и придуман. Не хотите - ради бога, ешьте дальше вилкой свой суп.
Эх, мог бы - плюсанул бы :) Золотые слова.
1. Можно, но чуть сложнее. :)
2. А теперь представте, что у вас есть базовый класс Storage, от которого унаследованы DB и File. И вы можете одинаково работать с объектом, представляющим, как файл, так и бд. Не задумываясь о том что это в данном конкретном случае. И использовать, скажем, файл для отладки и бд для итоговой системы. Пример несколько натянутый, но суть примерно такая.
3. Да какая разница как функции именуются. Вам приходится передавать параметр $db_pointer явно, а в оо случае он, конечно, тоже передаётся, но неявно. Рюшечки :).
4. Это я не понял. Это какие-то пхп заморочки, видать.
5. В большинстве процедурных языков.
File.open 'myfile.txt' do |file|
puts file.readline
end
И закрывать не надо - сам закроется либо при выходе из блока, либо при ошибке тоже.
db_add_string(), допустим, относится к управляющим функциям СУБД "Х". как будет выглядеть аналогичная функция для СУБД "У"?
Нет, не совсем. Потому как если нам нужно обеспечить поддержку _разных_ способов хранения данных, процедурный подход неудобен. Нужно изобретать велосипед для того, чтобы реализовать использование под одними и теми же именами _разных_ процедур. При помощи ООП же это делается просто: создаются абстрактные классы для, скажем, управления подключением и отображения набора данных, после чего реализуются наследники для каждого конкретного метода хранения. И только в реализации классов-наследников мы будем писать конкретный код — как и куда сохранять, удалять, извлекать...
При использовании всего этого дела мы можем даже не знать имен классов конкретной реализации. Созданием же нужного экземпляра (или возвращением его класса), а также регистрацией способов хранения будет заниматься factory. Например:
var DB: TDataBase;
DB := DBFactory.GetConnection(Config.ReadString('data_storage'));
или
type TDataBaseClass = class of TDataBase;
var DBC: TDataBaseClass;
DBC := DBFactory.GetConnectionClass(Config.ReadString('data_storage'));
> Нужно изобретать велосипед для того, чтобы реализовать использование под одними и теми же именами _разных_ процедур.

Указатели на функции ещё никто не отменял, суть - те же виртуальные методы и события.
Предлагаемое Вами называется изобретением велосипеда. Причем абсолютно излишним.
Я не спорю с тем, что ООП даёт некоторые удобства, но всё-таки этот "велосипед" существовал задолго до прихода в массы ООП подохода. И ничего такого революционного в этом пришествии не было, ООП просто унифицировал большое количество различных велосипедов существовавших до него.
А кто говорит про революцию? Нормальная эволюция, дающая не некоторые удобства, а весьма существенные.
Ну в питоне например есть такое понятие file like object. Это объект, который ведет себя как файл. Он должен отвечать определенному интерфейсу. В частности иметь метод read(). Этот метод читает строку, причем не важно откуда. Объект скрывает сущность открытого ресурса. Это может быть файл на диске, а может и страница полученная по http, а может еще куча всего. В контексте использования этого объекта и его метода read() это совершенно не важно. Вот вам приемущество ООП подхода и пример полиморфизма.
Читая комментарии это преимущество я понял и даже осознал, так как дали реальные примеры из реальной жизни а не абстрактный поворот треугольников и квадратов. Спасибо. Всем.
Не хочу ломать Вам кайф, :) но это преимущество называется паттерном "Интерфейс", и ничего объектно-специфичного в себе не содержит.

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

На мой взгляд, понятие интерфейса и есть та ключевая штука, которая позволяет уменьшить сложность и увеличить гибкость системы.
ну, если так брать, то в Си это было и без ООП - потоки, которые тебе и в файл выведут, и на экран или какое печатающее устройство, или в порт что запишут.
А вам не кажется, что это как раз тот же ООП, только искуственно записаный полностью процедурно? Или наоборот - такая процедурная запись это как раз то, из чего выросло ООП и разница здесь - только на уровне синтаксиса?
Еще приятно когда за высоту например объекта отвечает переменная obj1.height, obj2.height, а не height_of_obj1. Не прада ли?
А вот наследование мне не кжется сутью объектов. Это всеже скорее упрощение их создания и все.
не пойму чем отличается obj2.height от obj2[height] ?
Тем что тогда 1 первом случае можно добавить метод obj2.heightX2() умножающий высоту на два, а в массив функцию можно добавить не везде.
Тем, что можно объявить метод setHeight в котором поставить проверку на тип добавляемых данных, а с вашим кодом я могу написать следующее:
obj2[height] = "А хрен тебе, а не высоту!!!";
Кстати, отсутствие строгой типизации в PHP порождает эту проблему, в С++ ее как бы нет, но мы же обсуждаем PHP
наследование, вообще-то, один из ключевых понятий ООП, как раз после абстракции, о которой только что сказали вы.

а вообще, правильнее, будет сделать высоту так:
class obj
{
private int height;
public int getHeight()
{
return this->height;
}
}
почему надо скрывать переменную и использовать метод? потому что, если height сменится с целочисленного на вещественный, то придется учитывать возможности ошибок во всех местах программы. а так - мы используем метод getHeight(), в котором вся реализация инкапсулирована внутри.

Я описал все это упрощенно) Хотя часто использую публичные переменные. И для высоты скорее всего использовал тоже публичную. Видимо пока не встречался с подобными проблемами.

А наследование - это конечно очень полезно, но мне всеже, кажется, что суть не в этом. Я склонен считать, что это скорее инструмент.

инструмент - это то есть, какая-то опция?

вообще, где-то в 60% случаев, если можно обойтись без наследования, то использование ООП - изыбточно.

Используя объекты, вы ведь не оперируете наследованием? И его используете лишь для упрощения создания нового класса. Ведь так? Это просто позволяет использовать какую-то заготовку для создания нового класса.

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

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

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

а вот выбрать тот уровень абстракции, на который надо ориентироваться, - это основная задача программиста. на примере:

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

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

а процедурный подход предполагает более или менее однородную структуру программы, которая реализует более или менее линейный процесс.

Про область видимости я с самого начала написал)

А вообще я вэб-программер на php. Так что множественное наследование и прочие радости мне неведомы)

А насчет мира, могу сказать только то, что чаще удобнее без наследования. Например очень редконадо чтобы у стола было свойство "диаметр" унаследованное от ножки. Удобнее чтобы у стола был потомок "ножка" а у нее "диаметр"...

Ножка - потомок стола? :) Оригинально.
ага и свойство стола "диаметр", равное диаметру ножки - самый классыный пример неправильного использования наследования
Стол с диаметром столешницы равным диаметру ножки - это пень :)
В данном случае ножка - потомок. body ведь потомок document? Правильнее сказать не потомок а childNode или составная часть...
Смысл-то я понял. Просто неправильными словами названо - из-за этого возникает путаница.
хрень. вы путаете XML-ные понятия родитель-потомок из области графы-деревья и ООП. в XML боди является потомком, потому что вложен в тег документ. в наследовании же потомком является "эволюционный" потомок - т.е. тот же класс, но измененный и/или дополненный.

между ножкой и столом не возникает связи наследование (что стол может наследовать от ножки? а ножка от стола?) здесь более уместна агрегация (наследование) - включение объекта ножка внутрь объекта стол, раз уж нам так захотелось вообще выделить ножку.

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

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

но такой уж Вы, видимо, вэб-программист на php...

Я уже согласился, что неправильно выразил свою мысль. Я просто хотел сказать, что наследование для меня лично не является ключевым фактором ООП. Хотя бы по причине того, что чаще используется агрегация - именно включение одного объекта в состав другого.

Например, есть класс описывающий таблицу бд. Для класса описывающего бд было бы неуместно наследовать свойства и методы класса описывающего таблицу.

Просто видимо мне встречаются чаще задачи такого рода а не с млекопитающими. И суть наследования я понимаю) Но всеже мне не кажется это ключевым фактором. Это всего лишь способ упростить создание другого объекта. Это хорошо, и даже очень полезно, но суть то не в этом.

хотите задачку? ) возможно баян.
есть класс квадрат и класс параллелограмм. кто кого должен наследовать? ))
квадрат == параллелограмм
параллелограмм != квадрат
все очевидно
То есть, вы таки отнаследуете квадрат от параллелограмма? :-)
Разумеется нет. Квадрат - это скорее объект класса Параллелограмм.
Хотя без контекста задачи все рассуждения будут голословны.
Совершенно верно. Автор правильно написал, что это боян, но, по-видимому, боян не стареющий.
Простое наследование квадрата от параллелограмма может нарушать принцип подстановки Лисков (кажется, последний из ключевых принципов ООП, не упомянутых здесь), если базовый класс обладает методами, которые могут нарушить инвариант квадрата.
эм, я уже плохо помню школьную математику после вышки ^^', какой же метод от П. не может быть передан К.?
Ну, к примеру, «изменить длину стороны». Непонятно, конечно, кто в здравом уме будет его реализовывать, но всё же. Проблема отчётливее видна в примерах с квадратом и прямоугольником или окружностью и эллипсом. Студентов удобно ловить :-)
ну не знаю, "изменение длинны стороны" можно просто переопределить в К. это подначка студента ради самой подначки...
Как переопределить? Есть несколько вариантов: изменять заодно и другую сторону, игнорировать, или кидать ошибку. Все они противоречат здравому смыслу. Напоминаю сущность принципа Лисков (substitutability): объекты подтипа могут использоваться там же, где и объекты базового типа, не нарушая логики программы. Переопределение метода, не нарушающее инвариант квадрата, будет нарушать контракт базового класса, постусловие данного метода.
Этот пример обсасывался миллион раз.
сделаю закидон...
для параллелограмм, унаследованного от квадрата, можно добавить еще одно поле - ширина. вот и параллелограмм.
не так ли? )))
а как-же угол у основания, или высота, или что-нибудь позволяющее указать «наклон» ?
Потомок у стола - стол складной. А ножка и столешница - интерфейсы :)
Нет, это агрегированные объекты.
Интерфейс же в случае ООП это на самом деле указатель на таблицу методов. Другое дело, что в публичной части агрегированные объекты могут предоставляться как интерфейсы на их ТМ, а не как указатели на агрегированные экземпляры соответствующих классов.
а я вот кстати интерфейсы так и не распробовал, по мне так уж: у стола абстрактный предок стол, который использует не менее абстрактный объект ножка))) который если !isset то получается доска))
это не преимущества ооп
в паскале был тип-запись и без ооп
а вот наследование - наследование да
А разве там поддерживались методы?) И кстати зачатки ООП в паскале есть. Просто реализовано через известное место. И когда в 6м классе я ходил в кружок по нему, я не понимал смысла ООП вообще)
я про obj1.height
а ооп в паскале, когда оно там было реализовано, было очень даже на уровне
просто ооп тоже развивалось за последние 20 лет ;)
В книге Thinking in Java хорошо описано про наследование. Им часто злоупотребляют. Надо чаще использовать агрегацию, и реже наследование.
Наследование - изменение поведения
Агрегация - изменение сущности (расширение или уточнение. Переход от абстрактного к частному)
Плюс можно легко освободить память unset($db); а так придется удалять все переменные через кучу отдельных unset...
На деструктор я бы пологаться не стал, в PHP он работает через раз!
1. инкапсуляция (не путать с сокрытием) - каждый объект представляется в виде состояния и группы методов работающих с этим состоянием.
2. следствие из первого - полиморфизм - замена одного объекта на другой в одном месте программы позволяет изменить некоторый аспект поведения программы.

объекты - это как детали конструктора лего - каждая деталь имеет свой цвет и форму, и с помощью некоторого интерфейса может быть соединена с другой.
Как вам WIN32 API? Это - процедурный подход.
Более безумного примера привести не могу... А без примеров тут сложно что либо доказать.

Хотя, плохое проектирование ООП, как мне кажется, худшее зло, по сравнению с плохим процедурным подходом. Просто, такого наворотить можно...
Как раз WinAPI — хороший пример системы, спроектированной в духе ООП, но реализованной в процедурном языке.
Инкапсуляция налицо: постоянная работа с объектами (хэндлами), о внутренней структуре которых ничего не известно, но которые обладают состоянием. Собственно, они часто так и называются, объекты ядра.
Полиморфизм: есть ряд функций, которые работают с разнообразными объектами, вызывая нужный код. Например, CloseHandle одинаково успешно закроет открытый файл, канал или дескриптор потока.
Наследование и обмен сообщениями — можно вспомнить оконную систему.

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

P.S. По ходу обсуждения тут больше вспоминают ООП в PHP, тут я ничего не могу сказать, некомпетентен.
Если бы это было ООП то роль CloseHandle выполнял бы деструктор, который чаще всего вызывался бы автоматически. Кстати, помимо CloseHandle были ещё и функции типа ReleaseDC и т.д.

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

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

Кто сказал, что деструкторы — непременный атрибут ООП? Понятие детерминированного деструктора вообще только в C++ существует (и в D, наверное, как в его улучшенном клоне). Какие деструкторы, к примеру, в Smalltalk?
«Actually I made up the term "object-oriented", and I can tell you I did not have C++ in mind». — Alan Kay
Надо отличать ООП как парадигму и его реализацию в языке программирования.
В Паскале тоже есть деструкторы, в PHP 5 есть. И вообще это удобная штука часто.
Ах да, Object Pascal забыл.
Насчёт PHP опять ничего не могу сказать. Но недетерминированные деструкторы (а какие ещё могут быть в языке со сборкой мусора?) в контексте WinAPI малополезны, ибо для освобождения ресурсов непригодны. Тут в дело вступают механизмы а-ля IDisposble в .NET.
Ну да ладно, это уже частности.
Я много работал с WinAPI, потому смело могу сказать — пример хороший, но реализация уродская.

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

Во-вторых, нет единообразия в именовании функций — не то, чтобы в пределах некой предметной области, но даже в пределах одной библиотеки. Даже такой новый относительно общего наследия WinAPI пример, как shell32.dll имеет функции с префиксами Sh и Shell.

В третьих, нет единообразия в обращении с объектами. Например, для HWND часть свойств назначается/получается вызовом методов, а часть — через Send/PostMessage.

В четвертых, не всегда наследуется поведение. Попробуйте, например, убрать рамку вокру объекта COMBOBOX — шиш. Хотя формально COMBOBOX суть наследник от HWND, и в других таких же объектах (например, EDIT) рамка убирается. Кстати, именно в этом причина того, что в IE ничего не меняет. Мне в свое время пришлось даже писать собственный комбобокс, понятное дело с кучей допвозможностей, типа нескольких кнопок.
Попытаюсь ответить общими словами и если надо, то сошлюсь на примеры.

Как правильно заметил SmileSRG "Инкапсуляция, наследование, полиморфизм." И это технические инструменты ООП, благодаря которым можно в значительной степени ускорить разработку приложний, до грандиозности улучшить читабельность и "понимабельность" кода, облегчить во много раз поддержку и расширение проэктов. Почему? Потомучто человеческий мозг мыслит объектно, а не процедурально... так уж повелось...
Если нужны примеры, то могу привести по любому пункту.
UFO landed and left these words here
попробуйте нарисовать схему работы программы на процедурном подходе, а потом постройте UML для объектного. это многое поставит на свои места.
Только после этого следует ещё нарисовать процедурную схему работы каждого метода. :)
я имел ввиду понимание окружающей среды, как взаимодействие между объектами=)
Думаю что нет каких-то явных преимуществ.
Чем больше занимаюсь программированием тем больше убеждаюсь что большинство подходов оисываемых в книгах по ООП можно с небольшими изменениями применять при процедурном подходе.

Думается что тут немалую роль играет наглядность - разница между формализованной ОО моделью в UML и реализацией на большинстве современных ОО языков программирования (имеются ввиду не только чистые ОО, но и облдающие свойсвами) не такая большая, т.е. присутствует наглядность.
Главное преимущество - улучьшеная структура, что упрощает поддержку. Остальные преимущества следуют с 1 :)

А вообще обойтись без ООП можно всегда, так-же, как и задницу лопатой чесать. Только это не всем удобно.
Я думаю, что изначально нужно говорить о преимуществах объектно-ориентированного дизайна перед другими методами.
ООП просто позволяет воплотить в жизнь ОО-дизайн наиболее близкими к нему техническими средствами. Кардинальное же преимущество ОО-дизайна, заключается в близости этого метода к устройству человеческого сознания. Люди мыслят образами, их способностями и взаимосвязями с другими образами, а не последовательностями структурированных действий.
Конечно, можно ООД имплементировать и не ОО средствами, но зачем?
Многие знают только PHP и поэтому никогда не узнаю что даёт истенное ООП.
Язык PHP версии 5.2 (последняя версия которую я использовал), поддерживает от силы 10-15% возможностей ООП.

Кроме наследования, полиморфизма и инкапсуляции (три столпа),
ООП также предоставляет возможности делегирования и генерации событий, что очень удобно.

Можно посмотреть в сторону Java или C# и увидеть, как там всё элегантно.
угу, только в вебе события и данные разделены клиентом и сервером.
Присоединяюсь к вопросу.
Мне как не программисту очень интересно в чем координальное преимущество у ООП перед процедурным программированием.

Когда я слышу про ООП, мне не понятна одна вещь - где точка входа программы если везде одни классы?
Вот мне всегда было любопытно - какой смысл вкладывают люди в слово "координально" ?
Лафоре. Мне в свое время очень помогла. Только курить нужно с самого начала, даже если он пишет про известные вам вещи.
Мне кажется, что польза от ООП, реальная польза, видна лишь в крупных проектах.
Например стандартные библиотеки php очень неудобно использовать. Не смотря даже на то, что там относительно не много функций. Дело в том, что все находиться в одном измерении. Условно все функции братья и принадлежат какомунить модулю. При этом, что немаловажно этот модуль, лишь условная единица. Он не учавствует в именовании функции.
ООП же дает огромное преимущество. Мы имеем несколько объектов, каждый имеет набор методов применимый только к этому типу объектов. Какойнить метод может вернуть другой тип объекта, который реализует свои методы. При этом мы имеем стройную и понятную систему именований. Легче разбираться в библиотеках, проще запомнить названия методов, меньше надо передавать параметров.
Но свои проекты, особенно если они не очень большие, можно делать и без ООП. ООП зачастую плодит куда более многогословный и искусственно усложненный код. Здесь надо понимать что ты делаешь на этапе проектирования.
Вообще, я думаю что в веб иногда можно обходиться и без ООП, но в "большом" программировании ООП необходим. Почитайте паттерны проектирования. Они дают очень много реальной пользы.
Не специалист я, но по-моему ООП, придумали ради удобства подхода к программированию, то есть это как бы часть интерфейса написания программ. Хотя при грамотной организации программы и логично прописанных именах проблем нет.
Одного знания ООП недостаточно. Надо знать где его применить.
Прочитай книгу "Приемы объектно-ориентированного проектирования. Паттерны проектирования".
В принципе добавить нечего. В главе про графический редактор ты найдешь ответы на свои вопросы.
Всё, что там описано, можно сделать и процедурно.... НО боюсь, на это понадобится много времени, сил и фантазии.
Об ООП можно говорить в нескольких смыслах, которые часто путают внутри даже одного комментария.
Во-первых есть "концепция ООП", в которую входят три основных принципа, которые уже были раз двадцать были перечислены: инкапсуляция, полиморфизм и наследование. В чем заключаются эти принципы тоже говорилось, поэтому повторять не буду. При реализации этих принципов очень часто использовались схожие конструкции, которые обрели форму паттерна Класс. Однако этот паттерн так глубоко встроен в мозг и мышление современных программистов, что рассматривать класс как паттерн сейчас достаточно сложно. Кроме паттерна Класс, можно привести еще несколько паттернов, относящихся к "чистому" ООП, например, паттерн Конструктор, паттерн Интерфейс.
Далее, система может быть спроектирована с последовательным использованием принципов ООП, однако реализована на языке, в котором эти принципы не поддержаны (например, на ANSI C). Таким образом, второе понимание ООП - это степень отражения концепций ООП в том или ином языке программирования.
Теперь исходный вопрос можно переформулировать двумя способами:
1. В чем преимущества проектирования и описания предметной области с использованием концепций ООП и без использования концепций ООП?
2. В чем преимущества использования языков со встроенной поддержкой концепций ООП от языков без поддержки этих концепций?
Первый вопрос философский и я на него отвечать не буду. Философичность его в том числе в том, что утверждается, что стремление выделять объекты слишком встроено в кору головного мозга, как следствие описывать предметную область не в терминах объектов вроде как не удобно. Чем лучше ООП подход, скажем, правил вывода, используемых, например, в Prolog, я аргументировать не берусь, скорее всего областью применимости.
Второй воспрос более конкретный и более понятный. Когда в язык встроены некие паттерны это лучше, чем когда их нет (тут конечно нужно соблюсти зыбкую грань и не переборщить со встроенными паттернами). Лучше тем, что код получается понятнее, короче, нагляднее, поддерживаемее и т.п. большему числу программистов, знакомых с языком и предметной областью (при условии, конечно, что соблюдены другие требования к понятности, наглядности, поддерживамости и т.п.). Если мы реализуем полиморфичное поведение на С через указатели на функции в коде будет написано сложное и запутанное манипулирование указателями на функции. Если мы реализуем полиморфичное поведение на C#, то в коде будет написано манипулирование обобщенным объектом. Кроме того, если стандарт задан языком, то не нужно мудрить и придумывать велосипед, как называть функцию, инициализирующую состояние концептуального объекта, как называть функции, относящиеся к объектам, как называть поле, где будут храниться указатели на функции и т.п. И стороннему программисту, чтобы разобраться с "ООП-программой" на C, нужно будет сначала разобраться с тем как группа разработчиков решила в данной программе представлять термины ООП, потом разобраться с предметной областью, потом вникать в код. Чтобы то же самое сделать программисту на C#, изучить предметную область, потом вникать в код. На один шаг меньше. Кроме того компилятор берет на себя заботу о том, чтобы проверить за программиста, правильно ли он использует средства ООП.
Приведу еще несколько примеров, когда наличие какого-либо паттерна в языке лучше, чем его отсутствие.
Паттерн Интерфейс. В С++ его нет. Но его моделируют с помощью класса, содержащего (только) абстракные виртуальные методы. Для реализации интерфейса используют множественное наследование. Чтобы как-то отличать интерфейсы от классов придумали соглашение ставить букву I перед именем. А что если я не подчинился и назвал интерфейс по-другому? Мой последователь будет долго разбираться, что я имел в виду. В C#, Java такой проблемы нет (отличить интерфейс от класса), потому что концепция интерфейса введена в язык.
В языке Delphi реализован паттерн Фабричный Метод (виртуальный конструктор). Для реализации этого же паттерна в других ОО-языках нужно "городить огород".
Как резюме, прямая поддержка принципов ООП в языках весьма полезна, потому что
- делает хороший код понятным сразу большему числу программистов,
- позволяет преобразовывать мысли/требования/спецификации в код (в большинстве случаев) без вспомогательных конструктов
- позволяет понимать, создавать и поддерживать код сравнимо меньшими усилиями.
То, что даже на таких языках можно писать кривой код, я оставлю за скобками. Пока языки еще не настолько совершенны, чтобы запрещать писать "кривой код" :)
UFO landed and left these words here
Без ООП вы не получите в руки такую замечательную штуку как «отражения», не так ли? Хотя на 95% проектов можно легко обойтись и без этого.
В языке С++, например, нет никакого отражения. Если нужно, приходится делать руками. Аналогично, если моделируются классы на чистом С, то отражение тоже можно руками сделать.
Отражения - это уже плюшка выросшая из ООП. Также как ООП выросло из изоляции логики в отдельных файлах и модулях, которые в ООП уже превратились в классы.

Вам не кажется, что если один и тот же код сначала записать в виде классов, следуя всем канонам ООП, а затем позаменять всё на аналогичный процедурный код (как это делалось в примерах выше), то вы всё равно будете иметь нечто, соответствующее идеям ООП? Естественно, что обратное в общем случае - неверно. Более того: c моей точки зрения дело вовсе не в классах. Можно писать процедурный код завернутый в классы, а можно писать ОПП-код без классов. Если вы будете на С моделировать классы, абстракции и отражения - вы по суте получите тот же ООП, только синтаксически иначе записанный.

Для меня ООП - это концепция написания кода таким образом, чтобы его можно было эффективно повторно использовать, расширять и заменять. Такая аналогия: в ООП мы вместо того, чтобы просто прокладывать дорогу по кратчайшему пути из точки A в точку B, делаем на этой дороги съезды на другие дороги - это ничуть не ускорит поездку из A в B, но зато если вы захотите получить дорогу из A в C, расположенное рядом с дорогой, то вам это будет гораздо проще.
Я собственно именно про это и писал тремя коментами выше: есть концепция ООП, а есть реализация этих концепций в определенном языке. Две суть разные вещи. Что касается отражений, то они выросли не из ООП, а из необходимости иметь метаинформацию о коде для различных целей: для упрощения процесса разработки, поддержки всяких RAD-штучек, для упрощения интеграции разноязыкового кода и т.п. Пока был только С++ это делали вне языка, потом оказалось, что очень удобно, когда метаинформация поддерживается на уровне языка.
О, это вообще болезнь мэйнстрима - понимание ООП как использование ключевого слова class. Я сам сейчас тоже в той еще лапше ковыряюсь, тоже "на классах написаной". Наследование "для галочки" (которое реально никак не используется), зато копипаста хоть отбавляй. Объекты создаются только для того, чтобы дернуть у них тот или иной метод (группируем функции в классы, ага) - то есть никакого state у объекта, который можно было бы использовать, нет. И, конечно, стандарт де-факто для ПХП: в одном классе и базу дергаем, и логику делаем, и еще HTML echo-ми пуляем. Объектно-ориентированный подход, блядь.

Вот показательный пример (про отбивку операторов пробелами я даже не заикаюсь):

function DisplayBody() // copypaste from VzzPagedVideosBlock...
{
global $Lang;
$s=$this->QueryPages();
$s->execute();
$pages=$s->fetchColumn();
$s=NULL;
if ($pages<=0) {
echo "<div class='search-results empty'>";
echo '<p>' . $Lang->Sprintf('search-results-empty-1', $this->search_string) . "</p>\n";
$b = new VzzPopularVideosBlock(false, false, false, true);
$b->Display();
$b = NULL;
echo '<div class="clear"></div><p>' . $Lang->Sprintf('search-results-empty-2', $this->search_string) . "</p>\n";
echo "</div>";
return;
}
$this->pager->Display($pages,5); // ...except for page links number
echo "<ul class='videos_list videos_list-wide'>\n";
$s=$this->QueryList();
$this->pager->BindState($s);
$s->execute();
$this->DisplayListBody($s);
$s=NULL;
echo "</ul>\n";
$this->pager->Display($pages,5); // ...
}

function QueryPages()
{
global $DB,$Lang;

$s=$DB->prepare('SELECT videos_search_pages(:search_string,:pagesize)');
$s->bindValue(':search_string',$this->search_string);
$s->bindValue(':pagesize',$this->pagesize);
return $s;
}

function QueryList()
{
global $DB,$Lang;

$s=$DB->prepare('SELECT * FROM videos_search(:search_string,:order,:direction,:pagesize,:page)');
$s->bindValue(':search_string',$this->search_string);
$s->bindValue(':pagesize',$this->pagesize);
return $s;
}
Извените, но ваш код - гавно.

"global $Lang;" - вы слышали о паттернах? Зачем глобальная переменная? Просто внесите в список параметров или переменных класа...
Чтобы уничтожить переменную делает unset, но в функцие её вообще можно не трогать тк. она уничтожиться при остановке выполнения.

$b = NULL; // lang; // Display();

переделайте

VzzPopularVideosBlock::Display(false, false, false, true);

и т.д.
Конечно говно, я и привел его в качестве примера "как нельзя писать". Плохо то, что мне с таким трешем приходится сейчас работать, а делать The Big Rewrite нет ни желания, ни возможности.
Если системма, в котором написан код интересна, то в реврайтом могу помочь :)

а за пример - я сначало прочёл код, потом как настоящий тестировщик его поругал, а уже потом почитал то, что выше)
Спасибо за предложение, но у нас closed-source продукт :) А поругали Вы, бесспорно, правильно, там такие прелести каждые 5 строк попадаются.
Забавно, по-моему, этот код как раз и приводили как пример Г..
или я чего недопонял?
а оно похоже не поняло суть, когда отвечало
А главное, вот поэтому:

$DB->prepare('SELECT * FROM ...

Использование одной грамматики внутри другой для выполнения одной (причём несложной) задачи и является примером помянутой тут выше "акцидентальной сложности".
Смешение грамматик PHP-SQL PHP-HTML - это отдельный вопрос. Если со вторым ещё как-то справляются шаблонизаторы, то с первым всё сложнее. И не говорите, что существует идеальный ORM с генератором запросов покрывающим возможности SQL хотя-бы процентов на 80. И ООП тут не причём.

Вот разделение Контроллера-Модели-Вида сильно упрощающее разработку web, без ООП мне не представляется возможным
называйте человека "он" или "она", пожалуйста.
Зато характеризует моё отношение, хотя и невежливо
Полностью поддерживаю ilyily. То, что человек не ответил на ваш вопрос, не дает вам повода называть его обезличенно. Это просто моральное уродство. Чтобы понять это, желаю вам как-нибудь испытать к себе отношение как к вещи. Надеюсь, какие-нибудь выводы сделаете.
А здесь не идёт речь о конкретной личности. "Оно" обобщает людей, пришедших в программирование, потому что неплохая ЗП и камни таскать не надо, людей, которые пытаются набить себе цену, вворачивая умные слова типа "ООП" и "Веб 2.0", не обладая компетентностью в этой области.
Может, так и стоит написать? А то вдруг обнаружится, что эти люди на голову выше вас в проектировании. И меж собой общаются: "я ему говорю, что я на проектировщика пришел, а оно меня про ООП какое-то спрашивает."

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

А насчет проблемы низкой квалификации и высоких запросов - согласен. Ну это обусловлено превышением спроса над предложением. Скоро все выровняется.
ну, я где-то читал, что до выравнивания еще далеко - рынку далеко до пресыщения. к примеру, только у нас в регионе действует 5 международных (как они ся называют :) организаций, которые берут в штат программистов и натаскивают их на Java, чтобы создать тимы для разработки кучи всяких продуктов и поддержки САПы... и они все расширяются и расширяются.
бля... я понятия не имею как работает TCP/IP, что делать...
ну если вы не собираетесь сетевым программистом, все в порядке. по секрету скажу, даже в сисадмины вас возьмут :)
Я бы ответил так:
Основное преимущество ООП перед процедурным подходом состоит в возможности инкапсуляции методов и данных внутри объекта, что позволяет лучше структурировать код. Кроме того применение наследования и полиморфизма позволяет избегать дублирования кода в функциях выполняющих схожие действия.
Плюс, ходят слухи, что в PHP5 ООП работает быстрее, чем набор функций в файле.
UFO landed and left these words here
UFO landed and left these words here
Ну, с 1 функцией и одним методом - понятно, так как есть накладные расходы на создание объекта (фактически вызывается 2 функции: конструктор и метод), а вот если в классе 10 методов? Не тестировали???
UFO landed and left these words here
Я бы так сильно на 6-ой не надеялся.. Там ведь движок не переписывали, кажется??? Только поддержку Unicode встроили? Да и к тому же, пока он до 6.1 не дойдет в нем будет очень много багов. Все-таки 5-й пока безраздельно властвует...
Безраздельно властвует в каком смысле? Что вы имеете в виду?
В том смысле, что 4-ка умерла (обновлятся будет только по безопасности), а 5-ка постепенно оккупирует все хостинги.
вообще-то, довольно легко на пальцах показать, что использование ООП убыстрить программу не может.

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

ООП не быстрее, ООП удобнее. с другой стороны, оптимизируя реализацию ООП разработчики добиваются того, что эта "удобность" становится достаточно быстрой.
Зато использование шаблонов (как в С++) может.
А это во многом невозможно без ООП.
Сравнить достаточно, например, скорость работы sort()в С и в std::vector из STL
Каким образом шаблоны в C++ связаны с ООП? Обобщённое программирование (как это навал Степанов) и ООП ортогональны.
Нет, они не ортогональны. В широком смысле слова, объект — это набор данных и набор операций с данными. При этом неважно, пишем мы синтаксически a.f() или f(a) (яркий прмер — язык Ада, где объекты реализованы БЕЗ функций-членов). Поэтому основные элементы STL - контейеры, итераторы, в некотором смысле даже обобщённые алгоритмы — это "объекты", т.к. они типизированы и алгоритмы для них специализированы.
Пока мы не определимся с понятием ООП и объекта в частности, ни к чему не придём.
В классическом понимании объект должен обладать состоянием и идентичностью. Алгоритмы STL в объекты зачислить я не могу.
Эдак можно найти ООП в Haskell с его type classes.
Ну, окей, с алгоритмами я, пожалуй, перегнул :) Тем не менее, не будем забывать, что контейнеры — тоже один из китов STL, а уж они — объекты в чистом виде :)
В С++ — да. Но, следуя вашим же словам, никто не мешает разобрать объект такого вида на АТД и функции, с ним работающие.
Подобного рода статический полиморфизм широко распространён в ФЯ.
Гмм.. о чём спор? :) Изначально обсуждали, что ООП не тормозит программу. А теперь уходим в сторону того, что некую ООП-концепцию можно описать и не-ООП-средствами. На это возражений нет! :)
Я сам уже не понимаю, о чём тут спор :-)

Главное, не пытаться уложить всё подряд в прокрустово ложе популярных концепций, keep your mind open, так сказать.
это да, согласен.

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

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

Чушь, простите.
известный факт, простите. читайте литературу по тому же Джава, прочитайте лекции по методам трансляции.
Извините, неохота превращать это в пузомерку, но в компиляторах я съел если не собаку, то хотя бы её ногу.
Механизм virtual call в C++ вносит оверхед в виде одного (sic) косвенного вызова, с которым теперь неплохо справляются механизмы предсказания переходов современных процессоров.

HotSpot в Java отлично инлайнит методы, и Sun гордо об этом рассказывает.

В citeseer или google scholar можно нарыть массу интересного на предмет публикаций по оптимизации виртуальных вызовов и т.п.

Говорить, что ООП по скорости сопоставимо с эмуляцией — полная чушь.
Согласен с khayrov. Объекты местами способны круто затормозить, это правда, но в большинстве случаев тормоза вызваны неумелым использованием. Если опять вернуться к моей теме выше про обобщённое программирование, у товарищей вроде Александреску популярно показывается, как программа, построенная на одних объектах, компилятором может оптимизироваться чуть ли не до одной строки. При этом вызовы функций оказываются более "дорогими", т.к. препятствуют оптимизатору. Например, если вы передаёте куда-нибудь адрес функции, то функцию уже не получится за-inline-ить. Впрочем, это длинный разговор, и написать на объектах программу _умело_, я думаю, действительно сложнее, чем на функциях. Но по мере нарастания умения скорость сравнивается, а потом может и превзойти "сишный" подход.
Ключевое слово: компилятор. Компилятор может разорвать в клочья свой крохотный мозг, решая, какой из наследуемых методов должен быть запущен, на производительности кода это никак не отразится.
Вот это вообще бред )))
Можно ещё сказать что компилятор быстрее интерпритатора, а ассемблер быстрее C++.
А бинарные данные быстрее HTML передаются.

Знаете, вирусы в сотни раз быстрее приспосабливаются к изменениям окружающей среды чем более сложный человек
Применение ООП для больших проектов оправдано порядком в коде, оптимизацией ресурсов и быстрым понимания его работы последующими поколениями.
Практика сводит всё к тому, что подстроку 'ООП' надо поменять на 'вменяемого программиста' и сам по себе подход уходит на второй план. =)
Речь идет от лица программиста - себя же не поменяешь на другого "вменяемого".
Если верить Вашему высказыванию, то что бы добиться "порядка в коде, оптимизации ресурсов и быстрого понимания его работы последующими поколениями." достаточно переписать его с процедур на объекты. Я лишь с этим не согласен. Я считаю что всему своё место и процедурные проекты бывают большими и полностью удовлетворяющими вами перечисленным требованиям.
Конечно же это не панацея, просто это помогает (из личного опыта). Можно и в коробках дома вещи хранить, но шкаф, согласитесь, удобнее.
Рассуждения по поводу шкафа:
- Шкаф громоздкий его сложнее перенести в другую комнату нежели коробки. Часто приходится разбирать то что помешает его переносу или разбирать сам шкаф.
- Шкаф обычно весит больше, чем вещи, которые в нём лежат.
- Шкаф красивее коробок, и хранить вещи в коробках просто не круто.
- Кавардак на полках шкафа устроить не сложнее чем в коробках. Скорее проще, ведь если вещи в полной коробке были уложены аккуратно, - они не влезут в неё обратно если будут перемешаны.
- В каждой комнате можно держать определённый набор коробок, с вещами, которые в этой комнате используются чаще.
- В шкафе проще найти то, что тебе надо - всё на виду. Содержимое коробок надо однажды описать и потом периодически подправлять этот список.

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

P.S. Это была свободная импровизация и игра терминами коробки и шкаф, с попыткой аналогии между процедурами и ООП. =)
Простите за безграмотность! Нашёл у себя "в шкафе" и стало не по себе...
Очень давно ищу примеры по ООП, что было бы так — кода решения задачи в процендурном стиле, против кода решения задачи в ООП.
И затем плюсы/минусы подходов.

А не абстрактные примеры.
Кода вникал в COM, для меня отсался вопрос, если всё базируется на спецификациях, то почему просто не прописать спецификации для экспорта функции в Dll для аля COM объектов?
Пробовал сравнить скорость работы COM-объектов vs экспортированных из DLL функций.
это вопрос? :)
Мне кажется СОМ тормознутее
Я вот попробовал вникнуть в то, что Вы про COM спросили — и не вникнул :)
Если можно, ту же мысль, но более развернуто...
ок.
Довольно часто СОМ провозглашается как отличная технология для создания plugin-подобным программ, т.е. как бы из собираем новую программу существующих "кирпичиков" (ActiveX/OCX объекты).

При этом, на глазах у меня был Far, WinAmp, Photoshop - у них есть plugin архитектура, и всё прекрасно работает. И для понимания, как это работает внутри, намного проще, чем всякие IDispatcher, vTable и т.п.


Спустя лет 6-8, после попыток осознания СОМ, сама MS признала, что COM - говно, ибо всё можно сделать проще и красивее :)


Главным моментом в выступлении Бокса стала мысль о том, что объектно-ориентированные технологии обмена данными между программами, разрабатывающиеся компанией с начала 90-ых годов, изжили себя. По словам Бокса, технология OLE и ее наследники COM и DCOM оказались не столь универсальными и эффективными.
...
Заниматься дальнейшим развитием COM и DCOM компания Microsoft, по словам Бокса, не будет. Это, однако, не означает, что данные технологии немедленно отправятся на свалку истории. По словам Бокса, многие пользователи совсем недавно начали использовать преимущества, предоставляемые COM. Компания останется приверженной COM, но не собирается вкладывать значительных средств в ее совершенствование.
http://www.compulenta.ru/2004/1/29/44742… - Microsoft отказывается от компонентной объектной модели
На смену COM как генеральной линии партии пришёл .NET — тоже с компонентами, только done right. Но уж никак не какое-нибудь простая спецификация оформления DLL.
Почему бы сразу не сделать done right? :)
Ведь на c# проще, быстрее писать чем на C++/ATL.

з.ы. Я осознаю минусы виртуальных машин, но для моих задач они не критичны.
> Почему бы сразу не сделать done right? :)
Это такой ретроспективный пинок Microsoft? :-) Не смогли, вероятно. Во времена оные даже к C++ с подозрением относились.
В то время, когда делался ATL, MFC и сотоварищи, C# нам только снился :)
Это все равно, что заикаться о флешках во времена перфокарт и магнитных лент :)
Delphi реализация ООП для Win32, меня больше радовала чем COM/ATL :)
Как же не спецификация DLL? Вполне себе спецификация — наличие CLI-заголовка в PE :)
Довольно часто СОМ провозглашается как отличная технология для создания plugin-подобным программ
При этом, на глазах у меня был Far, WinAmp, Photoshop - у них есть plugin архитектура, и всё прекрасно работает
У программ с нативным кодом, как мне это видится, есть две основных объектных модели расширения (чисто процедурные плагины, типа TotalCommander-овских оставим в стороне):
1. Интерфейсы аля COM.
2. Базовые классы в SDK, от которых наследуются классы-плагины (например, Far, Foobar2000, etc.).
И у тех, и у других есть плюсы и минусы. И COM-подход в некоторых случаях гибче. Например, объект может инициализироваться разными способами — из файла, потока, урла, другого объекта, но делать одно и то же. В таком случае разумнее предусмотреть несколько интерфейсов инициализации, чем предусматривать все перегрузки в базовом классе (плюс, сами плагины могут предоставлять интерфейсы для "общения" между собой, о которых программа-хост не знает).
Кроме того, в обоих случаях vTable-ы и их внутреннее устройство совершенно не парят разработчика — пусть о них заботится компилятор. QueryInterface давно не проблема — она прозрачно сводится к вызову одной функции.

Хотя, конечно, проблем у COM-а выше крыши. Отсутствие разделения прав, параметризованных конструкторов, необходимость регистрации в системе (или геморрой с динамической загрузкой — тут уже никакой помощи от CoCreateInstance)...

Так что, наверное, правильно, что пора менять эту технологию на что-нибудь новенькое. Например, на .net-модель... :)
Необходимость появляется тогда, когда имеется множество объектов (классов) которые имеют сходное поведение но со своими нюансами.
Живой и яркий пример - DOM. Хороший пример использования ООП.
Все узлы document'а наследуются от Node, даже сам document. Node описывает логику работы с деревом, то есть вставка нового ребенка, удаление ребенка и т.п. а так же поддерживает ссылки типа parentNode, firstChild и т.д. От него получают производные классы такие как TextNode, Element, Document, CData и т.д. Но при наследовании дописываются только те методы и свойства, которые присущи каждому типу, а то что было прописано в Node передается в новый класс как будто бы вы там это и прописали. Далее от Element наследуются класс HTMLElement (который в свою очередь что-то добавляет), а от HTMLElement, к примеру, классы соответствующие каждому тегу HTML, такие как HTMLDivElement, HTMLBodyElement, HTMLTableElement и т.д. и каждый класс вносит свои нюансы. Теперь предположим вы пишите функцию которая работает с некоторыми объектами. Вы определяете какие методы и свойства вам нужны, и тем самым выделяете "минимальный" класс с которым вы будете работать. К примеру это Node. Тогда ваша функция может работать с любым объектом любого класса унаследованного от Node (в том числе и с объектом класса Node). То есть вам не важно что класс другой, для вас важно что это потомок Node, а это гарантирует что все необходимые методы и свойства у объекта есть. Таким образом можно писать функции, которые работают с большим спектром объектов, и проверка - подходит ли объект для передачи в данную функцию осуществляет еще на стадии компиляции (если не брать в расчет интерпретируемые языки). К тому же, если разбираться в этом, все выглядит прозрачно и просто. А достигается это за счет двух основных положений ООП наследование и полиморфизм. Есть еще и инкапсуляция, но это отдельный разговор.
Да это все можно сделать и без ООП. Когда я такое чудил - но поверьте, через некоторое время код просто невозможно поддерживать, и совершенно отсутствует reuse кода.
Не всегда ООП подходит для решения задач. Часто его пихают туда где это совсем не нужно и даже вредно, от этого и все проблемы с пониманием. DOM пример того как можно использовать ООП эффективно. Если нужно просто сгруппировать функции - это не ООП, это ближе к namespace, package, module.
Я думаю не правильно выразился :)
Мне ООП сам нравится, особенно его JS,C#,Java,AS3 реализации.

Но вот MFC, C++ — жесть. Особенно после c# :)

Пришла мысль, о том, что юзать ООП как фундамент мне нравится, но вот потом кодить свой код (сорри за тавтологию)в стиле ООП — как то муторно :), проще процедурками.
Сужу по своим не большим проектам на C#.
Кстати, несмотря на свою корявость, MFC-то еще вполне поддерживаемая технология. Вот, например, Feature Pack для VC++2008 включает кучу компонентов и улучшений именно под MFC. Так что пока рановато его хоронить, даже при всей прелести шарпа... :)
но вот потом кодить свой код в стиле ООП — как то муторно :), проще процедурками.
Наверное, именно оттого, что проекты небольшие :)
UFO landed and left these words here
Это везде так пишут.
Я же могу теже самые свойства и методы оформить через переменные и просто функции/процедуры?
UFO landed and left these words here
Можете.
А теперь представьте ситуацию, что рыбка каждого типа — это плагин, который подгружается в "аквариум". И у каждой рыбки плавники расположены по-разному, соответственно, чтобы рыбка плыла, нужно описать движения плавников.
Если каждая рыбка будет наследоваться от абстрактного класса "рыбка", определять положения и форму плавников и перегружать метод "плыть", то все просто и элегантно.

А в случае с процедурным подходом: как узнать, какой метод "плыть" вызвать для конкретной рыбки?
Описывать все возможные типы рыбок? А как же быть, если появится новая рыбка? Переделывать аквариум?
Хранить указатель на нужный метод в структуре, описывающей рыбку? Это и будет упрощенным понятием объекта, от которого Вы так стремились уйти в сторону процедурного программирования.
Зачем называть соискателя — «оно»?
ИМХО как-то разговаривали с коллегой на эту тему, появились такие мысли. Пришёл ООП, что он должен был дать? Ниразу не ORM-ы, операции над объектами и прочее. Это всё вторично, это следствия. Причина - разработка повторно используемого кода. Дабы я написал класс на подключение к БД и юзал его во всех своих проектах. Процедурами отвечали так-же - писали библиотеки. Так вот, внимание, вопрос. Оправдано ли ООП, если в итоге получается такая завязка классов друг на друге, что когда я подключаю один, я неизбежно тяну ещё несколько, которые он юзает. (скажем в моей MVC системе класс View ещё юзает Renderer который вытягивает специфичный для данного шаблонизатора Renderer( Smarty-Renderer/ Blitz-Renderer/ HTML-Renderer). Так ли уж хуже процедурный подход?

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

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

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

хотя я вот уж лет 5 как работаю программистом, а как-то пропустил, когда это объекты стали быстрее процедур ))). хотя верю - демосцена и не то еще творит...
Скорость объектов со скоростью процедур не знаю как сравнивать :). А что касается методов - то невиртуальным вообще не с чего быть медленнее процедур, а про виртуальные тоже написали - всего один уровень косвенности при вызове. Это даже меньше, чем разница между echo и print :)
Основная идея ООП - свести вместе данные и функции, которые могут работать с этими данными, в один объект. Вопрос: Зачем? Одна из причин - защетить данные от несанкционированного изменения функциями дригих объектов - так называемя инкапсуляция(Данные "прячутся" внутри объекта).
Без ООП невозможно применение модных нынче "agile" методологий (шаблоны проектирования, TDD и т.п), которые в свою очередь добавляют "гибкости" проекту в плане поддержки, расширения функционала.

Странно что успешны в большинстве своем проекты, которые не используют "ООП" в правильном виде. Например тот же wordpress, процедурный монстр.. но ведь завоевал неслабую популярность несмотря на кашу из бизнес/презент. логики и плохо "структурированный" код.
любой код написанный в стиле отличном от моего является плохо структурированным :)
Эм... Сорри, я не согласен. Agile никоим образом не есть следствие ООП. Простой пример: Agile Database development. Как вы сможете следовать всем принципам ООП в обычной реляционной базе? Не. В моем понимании Agile это лишь процесс, способный быстро адаптироваться под меняющиеся нужды заказчиков. ООП - один из возможных инструментов. И, может быть, не всегда уместных.
тогда это правильная постановка вопроса.
здесь применение ООп зависит от контекста работы.
Если та же Джава оопешная полностью то ты от ООП никуда не денешься.
Ну а если php - то все в твоих руках. Главное чтобы дырок не было.
Ведь бырки образует программист а не язык или ООП/неООП
Судя по комментариям, пора на хабре устроить опрос "Что такое ООП".
Лучше популярно(значит кратко) написать топик и основы обьяснить с примерами.
ООП - древнегреческое божество, породившее НЛО
ИМХО, не хорошо смеятся над некомпетентостью кандидатов на позицию. Ну и что, что оно не знало "правильного" ООП. Все когда-то такими были. Представьте, какое мнение было бы у вас о Google если бы вы однажды сходили к ним на собеседование и увидели позже такой фидбек:


Приходит оно на собеседование. Задаю общие вопросы. Заходит речь о его текущей работе и обязанностях. И слышу:
- Я когда пришёл, там вообще был ужас. Ну я стал понемногу вводить алгоритмы поиска, на красно-черные деревья всё переписывать...
- А зачем? В чём приемущество идеально сбаллансированных деревьев перед обычными?
- В идеально сбаллансированных все элементы находятся на одном уровне...
- Ну и что? Юзай обычные бинарные деревья. Чем сбаллансированные лучше?
- ... (у собеседника ступор)


Хых. Чую, сейчас минусов нахватаюсь. Но это мое ИМХО, и каждый имеет право на свое :).
1. Кандидаты сами начали разговор об ООП (за язык не тянул) и утверждали, что "в теме".
2. Кандидаты обладали достаточным опытом работы.
За минусы не бойтесь. Мне вот карму опять опустили ниже плинтуса, но особо не заморачиваюь.
А мы её обратно, топики же хорошие…
Почему минусов... когда-то все такими были...
или кто-то не был? сразу родился хорошим программером?
Плох тот кто не учится на своих и чужих ошибках.
Я более чем уверен что тот претендент после обьяснения ему что такое по настоящему ООП - через месяц бы ваял код не хуже других. Всё еще зависит от логики претендента... поэтому в гугл дают на собеседовании логические архитектурные вопросы.
Хотя как раз ООП это конечно архитектура и логика и есть :)
Инкапсуляция, полиморфизм, наследование - это все замечательно. Но это средства, которыми ООП достигает своей цели.

А цель, если я правильно понимаю г-на Г. Буча, заключается в описании ПО в терминах, удобных как для проектирования, так и для реализации систем.

Т.е., в терминах ООП удобно отразить объекты предметной области и их взаимодействие (начало проектирования), с тем чтобы, в дальнейшем, вычленить необходимые абстракции и организовать иерархические структуры (начало разработки).
Не только проектирования и реализации, но и сопровождения. Если система правильно спроектирована, то любые изменения и добавления функциональности (и новых сущностей) затрагивают как правило четко локализованный участок кода, а не весь проект вцелом.
Серебряной пули не существует. Каждой задаче — свой подход.
Позволю себе процитировать Алана Найта "Все знают, что популярнее, чем объекты и объектно-ориентированный дизайн, только горячие пирожки (и, естественно, каждый пирожок — это объект). Проблема в том, что тяжело прийти к соглашению, что же в точности он из себя представляет."
перевод статьи, если кому интересно http://ru.smalltalk.wikia.com/wiki/ПРИНЦИПЫ_ОО_ДИЗАЙНА

Смешно сказать, но сейчас нет единого определения что такое ООП и с чем собственно его едят. На данный момент существуют 3 класса ОО языков. "Чистое ООП" (Smalltalk, Ruby, Eiffel, ...), "Процедурное ООП" (C++, Java, C#, PHP5 и другие), "Прототипное ООП" (Self, Javascript, ...)
Именно поэтому ООП ИМХО это не "инкапсуляция, полиморфизм, наследование". Подобное определение не верно хотя бы потому, что указывает на детали реализации, а не на идеи. К тому же оно неподходит к целому классу ОО языков.
Вообще, довольно сложно так сходу выделить какие-то основные принципы ОО подхода вцелом, а не конкретной его реализации.
Согласен. От "инкапсуляции, наследования и полиморфизма" как определения ООП, данного в институте, у меня начинает дергаться глаз.
много хорошего слышал про Руби и иже с ним, хочу спросить: чем его ООП отличается от тех же Java, C#, PHP5?
- открытые классы
- любая сущность (даже объявление класса) является экземпляром класса сама по себе
- огромные возможности для метапрограммирования за счет динамической природы языка
- duck typing

Посмотрите, например, на RSpec (а в особенности на mock-и) и прикиньте, можно ли такое реализовать на Java или PHP.
Извиняюсь, но duck typing в Руби нет. Там строгая типизация, AFAIK. Duck typing в Питоне.
Кхм... Ладно, не обращайте внимания, будем считать я чушь сказал.
Хотя бы отсутствием разграничения доступа к полям и методам. Можно получить доступ или переопределить любой метод любого класса. Более того, можно модифицировать любой объект в runtime, добавив ему поле или метод.
Я больше по Смолтоку :) Хотя Руби очень похож на Смолток
Основные отличия "чистых" ОО языков от "нечистых":
1. Чистое ООП — принцип "всё объект". Никаких примитивных типов, и типов как таковых вообще. Это здорово всё упрощает.
2. Очень высокая степень рефлексии — "живое море объектов". Все объекты можно изменять и исследовать во время выполнения программы. Прозрачность системы сильно облегчает понимание того что программа делает и отладку.
3. (реализовано только в Смолтоке и потомках) Посылка сообщения — "единый интерфейс". Есть только один способ изменить состояние объекта — отправить ему сообщение, которое он обработает согласно своей внутренней логике. Это единая метафора для управления объектами. Как следствие простота и динамическая расширяемость языка.
Это в двух словах. Чтобы было понятнее нужно показывать на примерах.
Пост свелся к недавно опубликованой на хабре притче про математика и дурака.
Типичный тупой вопрос глупого человека из разряда "я бог а ты никто", попробуй сначала ответить на него сам.
Это просто вопрос на отвлеченную тему. Если собеседник не может просто поговорить об этом (тем более, как вы верно заметили, правильного ответа на такой вопрос не существует), а вместо этого впадает в ступор, то ну его нафиг такого кандидата. Человек либо просто не умеет рассуждать на отвлечённую тему, либо в таком стрессе от собеседования, что ничего не соображает. Ни то, ни другое положительно его не характеризует.
При наличии соответствующего инструментария можно оценить пользу от ООП, я, например, в восторге от C#. А то, как сделали объектную модель в PHP - язык не поворачивается назвать удобным. Мало того, что возросло количество ударов по клавишам при написании кода (замедлилась работа, сужу по собственной вынужденной практике), так ведь до сих пор никто даже не обеспокоился поддержкой этой объектной модели в инструментах разработки (где ты, IntelliSense :()

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

Если бы это был холивар, я бы записался в противники ООП (по крайней мере, в его PHP-инкарнации).
кто б еще кастинг к PDE/Zend/etc реализовал... а то бывает есть экземпляр полученый таким шаманством, что PDE его тип ну никак определить не может, а значит и code assistant работать не будет...

в итоге приходится иметь хаки типа
/**
* @return Megaclass
*/
function cast2Megaclass($obj){return $obj};


... а хочется банального ((Megaclass)$obj)->[и тут у нас список методов мегакласса],
или ($obj as Megaclass)->[и снова список мегакласса]


ну почему (int) есть, а (MegaClass) нету !? :(
И то и другое есть следствие особенностей языка. Плюс этот "хак" называется JavaDoc и комментировать подобным образомом свой код есть хороший тон.
под "хаком" подразумевалась уродливая и нафиг не нужная функция, единственная задача которой - прицепить к ней хинт через javadoc.


в оригинале подразумевалось, что очень хочется иметь возможность объяснить IDE какого типа у нас получится результат, скажем, unserialize()... пока только через "пустышку" с javadoc'ом (или phpdoc правильнее!?), больше способов я не нашел. а ведь потом эти "пустышки" вычищать еще приходится...
В Zend IDE можно просто в любом месте кода:
/* @var $obj MegaClass */
спасибо, меня уже просветили ;D

я такую конструкцию для свойств класса использовал, а при попытках прицепить к "обычным" переменным у меня не получалось из-за "гнусной" привычки сначала объявлять переменные, а потом использовать... в итоге я обламывался на том, что при присвоении ранее указанный "хинт" затирался... а я - дурак, думал что оно не работает :")
дал б + за комент, но не могу...
решением для intellisence может быть прописивание значения @return ObjectType в документирующих коментариях к функции... в некоторых случаях мне ето помогало.
Хм... народ спорит о преимуществах и недостатках ООП. А зря. Их и так все знают. Полиморфизм и инкапсуляция тут не главное.

Я же хотел обратить ваше внимание на следующий тип "программистов":
1. низкая компетентность в программировании вообще; поверьте, те люди, что ловятся на таких вопросах, одинаково херово пишут и процедуры, и классы;
2. следуют мейнстриму и кричат на каждом углу, какие они объектно-ориентированные, дабы набить себе цену на собеседовании; повторяю, в этом вопросе они вообще некомпетентны;
3. многие из вас с ними учились и работали; они пришли в отрасль, потому что непыльная и прибыльная.

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

Есть класс-ориентированное ООП (C++), а есть прототипно-ориентированное (JS). Опять же, это немного разные подходы с разными преимуществами.

ООП в PHP очень далеко от принципов ООП, сформулированных Кеем. В PHP это немногим больше чем инструмент группировки функций.

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

В Smalltalk нет вызовов методов, но есть процедура отправки сообщения. При чём, отправитель не обязан (но имеет возможность) знать, есть ли в целевом объекте метод для обработки этого сообщения. А получатель, в свою очередь, не обязан сообщение обрабатывать, но и может, скажем, обработать неизвестное ему сообщение.

Такой подход позволяет понизить до минимума связность системы. Каждый объект существует в абсолютной изоляции от других и может быть легко заменён. Низкая связность == лёгкость модификаций == повторное использование. В понижении связности и была одна из целей создания Smalltalk как объектного языка, да и, наверное, одна из целей ООП в общем.

Как заявлял сам Кей, отказ от идеи обмена сообщениями в пользу вызовов снижает эффективность всей идеи.
"Я придумал термин "объектно-ориентированный", и вот что я вам скажу, я не имел ввиду С++."
— Алан Кей, OOPSLA '97

и ещё две цитаты которые наилучшим образом отражают мои мысли после прочтения этой ветки:

"Основная проблема в сообществе программистов на С++, это попытки использовать стандартный С++ либо как облагороженный С, либо как Smalltalk для бедных."
— Бьярн Страуструп

"Говорить, что Java проще чем C++ это, как утверждать, что К2 ниже, чем Эверест."
— Ларри О'Браен (редактор журналов Computer Language и Software Development).

вместо C / C++ / Java попробуйте подставить названия других лодок.
.. ООП это когда ты набираешь текст и тут у тебе выпадает список вариантов .. %)
не, тогда ООП - это когда можно перетаскивать объекты с панели инструментов на шаблон будущего "приложения".
Прочитал, задумался сам. Тема далеко не такая очевидная. Я, по логике автора, дегенерат?

Если уж сказали "А", то будьте любезны, говорите и "Б". Давайте сами опишите преимущество ООП перед процедурным программированием. А, слабо?

В этой ветке уже достаточно написали, что такие вещи достаточно тяжело сравнивать (если вообще корректно), а вот у автора все просто и легко, ага. Имхо, ответ напршивается сам собой: вот такие вот ОНО, как автор, и сидят при приеме на работу и считают себя мега-программистами и теоретиками, основавшими подходы, заслуживающие Нобелевской премии во всех областях знания. Грубо? Сами начали.
Ну и еще небольшая ремарка.
Допустим я плотник, должен ли я знать отличия дерева от камня? Думаю аналогия ясна. И плотник и каменщик могут делать, по большому счету, одно и то же, но с разным подходом, разным инструментом и разным материалом. Так и в этом случае. У меня все.
Я думаю тебе стоит внимательнее вчитаться в статью и комментарии самого автора. Ситуация в том, что программист сам начал расхваливать себя как знатока ООП, а в итоге показал полную некомпетентность в программировании вообще. Цель - раскрутить на большую зарплату.

Кстати автора я знаю лично. Он достаточно хорошо разбирается в программировании и в ООП в частности.
если он такой крутой в ООП, он должен был хотя бы перечислить основные объектные концепции, которые как раз и позиционируются во всех учебниках как "превосходство". а неоднозначность - в оценке этого превосходства.
И вам советую перечитать топики и комментарии автора о чём этот топик.
я не про автора, я про "оно". так что советую вам не советовать мне перечитывать топик =)
Различие между процедурным программированием и парадигмой ооп мне кажется как различее между радиоустройством сделаным из транзисторов, сопротивлений и емкостей или собранным на микросхемах. В последнем случае мы имеем очень сложные схемы выполняющие свои задачи, но имеющие довольно простой интерфей- и мы способны сделать гораздо более сложные устройства. Я немного грешу ибо говорю о компонентной парадигме, но она идет рука об руку с ООП. Хотя стоит признатся что хорошо спроектировать классы это почти искуство. Эрик Гамма сказал, что вы поймете паттерны лишь когда почуствуете структурную боль от плохого дизайна приложения и увидите как удачноее решение (распределение сложности и обязанностей между классами и тд) принесет облегчение! Чтоб понять всю мощь ООП стоит посмотреть на примеры хорошего ООП дизайна - например код Eclipse, Spring Framework, Ruby on Rails - и попытаться представить как бы это выглядело на процедурном языке(получилось бы чтото типа winapi)! PHP не очень выразительный язык и в нем много атавизмов - попробуйте ruby и почувствуете кайф ООП.
Главное преимушества ООП
1.Конструкторы и Деструкторы.
{
Profiler P("some section name");
[..code..]
}
По входу обьект будет создан, по выходу уничтожен. Про чистку памяти я и не говорю
2.Закрытость - обьект это систама сама в себе, и сама по себе ничего кроме себя сломать не может
3.Наследование и другие полиформизмы.. не так уж и полезны. Но иногда жизнено неоходимы. В С++(общем понимании). В GUI, и тд.. А вот и в пхп я лично пока применения не нашол

Главное не заморачиваться с ООП, потому что ООП это круто.
Когда мы с виндов с их С++ перешли на работе под blackbin\uclinux на котором НЕТ нормального С++ нам пришлось забыть про классы.
Начали делать generated code ( аналог Tau SDL компилятор )
Результат понравился намного больше. Особенно своей неубиваемой отказоустойчивость.
(кто не понял - на входе "псевдо код с классами" на выходе километровый чисто процедурный код( не читабельный))
Программа, которая пишет программы - вот это я люблю.
Могу кстати выложить кому интересно
Смесь С и Lua , прогоняем через препроцесор, получаем файло.
Лучше опишите саму идею в отдельном топике.
Обьект построен как привычные нам обьекты в реальном окружении.
Маленький пример:
Обьект - яблоко, либо автомобиль. И все становится ясно. Врубитесь!
У автомомобиля есть методы
выжатьСцепление(положение_педали)
установитьРычагПередачи(положение)
выжатьГаз(положение_педали)
Обьект Человек может вызывать эти методы (он уже умеет превратить силу нажатия педали в положение педали)
У обьекта Автомобиль есть и другие методы и компоненты о которых обьекту Человек знать не надо
К плюсам ООП:
+ доступность кода - самодокументируемость. Как насчет вернутся к коду через год или оддать на суппорт кому-то?
+ клас - это сущность со всемы вытекающими последствиями (мы думаем сущностями)
+ юнит тестирование - это тестирование одной конкретной сущности (Автомобиля) и обьект Человек тут не имеет значения.
+ паттерны програмирования - куча класных подходов, которые и так у нас в голове :)
+ ТДД, ХР
ООП - в голове, а не в "классах"

но если язык прямо поддерживает (синтаксисом) эту парадигму - то почему бы этим не воспользоваться, меньше шума, больше сигнала

по-моему, вы на собеседника зря накинулись - иногда трудно сформулировать и изложить то, что чувствуется спинным мозгом
Only those users with full accounts are able to leave comments. Log in, please.