Здравствуйте, deniok, Вы писали:
D>С помощью такой аргументации можно доказать, что почти любая объёмная библиотека, написанная на С в 80-90е годы — ООП. D>Например, ODBC. Хэндлы есть — инкапсуляция. Функции на хэндл вызываются — сообщения.
Так может потому так резко и распространились ОО-языки (т.е. языки с поддержкой ООП), потому что люди уже реально использовали ООП на неудобных для этого средствах, а потом получили средства. позволяющие делать то же, но удобнее и надежнее?
Здравствуйте, deniok, Вы писали:
D>Слушайте, по-моему здесь все обалдели.
D>С помощью такой аргументации можно доказать, что почти любая объёмная библиотека, написанная на С в 80-90е годы — ООП.
Здравствуйте, fmiracle, Вы писали:
F>Так может потому так резко и распространились ОО-языки (т.е. языки с поддержкой ООП), потому что люди уже реально использовали ООП на неудобных для этого средствах, а потом получили средства. позволяющие делать то же, но удобнее и надежнее?
Не так уж и резко они появились.
Даже если считать от момента появления С++ (1983), прошел десяток лет,
прежде чем что-то реально сдвинулось.
А если считать от Симулы, то вообще не быстро все произошло
Здравствуйте, Odi$$ey, Вы писали:
OE>winapi — ООП? хм..
На самом деле, в WinAPI действительно чётко прослеживается ООП-подход. ООП базируется на трёх китах — инкапсуляция, наследование и полиморфизм. Всё это в WinAPI есть.
Инкапсуляция
WinAPI инкапсулирует объекты с помощью хэндлов, причём эта инкапсуляция получается намного сильнее, чем в типичной программе на C++. Мы не только ничего не знаем о внутреннем устройстве объектов, которые скрываются за хэндлами, — мы не знаем также их размер и местоположение. Объекты, с которыми мы работаем на уровне WinAPI, очень тяжело "испортить", перезаписав их память, вызвав для них неправильный метод и т. п. По сути дела, единственный способ сделать что-либо с объектом — это использовать связанный с ним API, то есть его интерфейс. Таким образом, в WinAPI очень чётко прослеживается разделение интерфейса (API) и реализации — это и есть инкапсуляция.
Наследование
В WinAPI наследование наиболее ярко проявляется в случае с оконной системой. Сравним два фрагмента.
1. Гипотетический оконный API на C++:
// Создаём класс окна для нашей программы...class CMyWindow : public CDefWindow
{
virtual int HandleMessage(...)
{
// Обрабатываем сообщение.return CDefWindow::HandleMessage(...);
}
};
CWindowFactory::RegisterClass(CLASS(CMyWindow));
// ...и объект этого класса.
CDefWindow *pWnd = CWindowFactory::Create(_T("CMyWindow"), ...);
2. WinAPI:
// Создаём класс окна для нашей программы...
LRESULT CALLBACK MyWindowProc(...)
{
// Обрабатываем сообщение.return DefWindowProc(...);
}
WNDCLASS wc;
wc.lpfnWndProc = MyWindowProc;
wc.lpszClassName = _T("CMyWindow");
RegisterClass(&wc);
// ...и объект этого класса.
HWND hWnd = CreateWindow(_T("CMyWindow"), ...);
Как говорится, найдите 10 отличий. С точки зрения синтаксиса фрагменты, безусловно, различны. Но с точки зрения семантики разницы нет никакой.
В этой связи я не очень понимаю аргумент о том, что можно передать функции GetWindowText любой хэндл. Вот например:
HFONT hFont;
GetWindowText(hFont, ...); // ошибка
GetWindowText((HWND)hFont, ...); // всё ОК
CFont *pFont;
pFont->GetWindowText(...); // ошибка
((CWnd*)pFont)->GetWindowText(...); // всё ОК
Разница, опять же, только в синтаксисе.
Полиморфизм
Полиморфизм тоже удобно рассмотреть на примере окон. Опять обратимся к гипотетическому примеру.
И в том, и в другом случае меня не заботит, к какому классу относится каждое из дочерних окон. Я могу задизаблить их все, используя единый интерфейс. Это и есть полиморфизм в действии. Аналогичным образом полиморфизм работает, когда мы ждём на произвольном объекте ядра с помощью WaitForSingleObject или, например, работаем со стримом через ReadFile/WriteFile — вне зависимости от того, файл ли это, пайп или драйвер.
Или рассмотрим такой пример:
SelectObject(hDC, hGdiObject);
По сути дела, это ничто иное как мультиметод. HDC скрывает от нас конкретную разновидность контекста (экран, принтер, память), а HGDIOBJECT — конкретную разновидность графического объекта (перо, кисть, фонт и т. д.). Мультиметоды не поддерживаются напрямую ни в C, ни в C++. Что не мешает использовать их в WinAPI.
Помимо основных концепций ООП, в WinAPI можно проследить и кое-какие паттерны проектирования. Например, CreateFile и CreateWindow — это по сути дела фабрики объектов. FindFirstFile/FindNextFile реализуют итератор. Окно, содержащее дочерние окна, может выступать как композит или декоратор — и в том, и в другом случае мы работаем с родительским окном, не заботясь о структуре окон внутри него. И т. д.
Что характерно, внутренняя реализация WinAPI очень удобно делается на классах. Например, оконная подсистема в Windows CE именно так и написана. Поверх WinAPI тоже очень легко положить "объектную модель". Многие популярные библиотеки, включая MFC и ATL/WTL — по сути дела тонкие обёртки над WinAPI. Они обеспечивают синтаксические удобства (вроде уничтожения объекта в деструкторе), но объектная ориентированность итоговой программы — не их заслуга. И это не случайно.
Одним словом, нужно провести чёткую грань между концепциями ООП и синтаксисом, поддерживающим эти концепции. Конценции ООП работают в WinAPI в полный рост. Ну а синтаксис — он уж какой есть.
--
Я думал, ты огромный страшный Бажище,
А ты недоучка, крохотный Бажик...
Здравствуйте, VladD2, Вы писали:
VD>>>Спроектировать большую систему в терминах модулей просто невозможно. Т>>А ничего, что самые большие системы именно в терминах модулей и проектировались? VD>Примеры, плиз, в студию. Я лично вижу другие примеры. API Виндвос и Линукс имеют выраженную ООП архитектуру.
Нуу.... Они почти ООП
Одна только оконная процедура в Windows без возможности передать контекст чего стоит. В Линуксе тоже не лучше дела — API для работы с локалями и временными зонами абсолютно анти-ООПшный.
Здравствуйте, deniok, Вы писали:
D>С помощью такой аргументации можно доказать, что почти любая объёмная библиотека, написанная на С в 80-90е годы — ООП. D>Например, ODBC. Хэндлы есть — инкапсуляция. Функции на хэндл вызываются — сообщения.
Я подозреваю, что зависимость строго обратная — библиотека может стать большой и популярной, только если она грамотно спроектирована.
Причём бог с ним с ООП. Во многих областях можно прожить без наследования и полиморфизма. Другое дело — инкапсуляция. По сути дела то, что ты перечислил (хэндлы и функции, которые для них вызываются) — это она и есть. Так вот, без неё большую библиотеку просто не написать, потому что любое изменение в ней будет приводить к поломке существующего кода у юзеров, и очень быстро им это надоест.
Вообще инкапсуляция, разделение интерфейса и реализации — это универсальный принцип, он вовсю работает не только в программировании, но и в технике, да и вообще по жизни. Люди пользуются им не одну сотню лет. Чего, кстати, нельзя сказать про наследование и полиморфизм. Это уже гораздо более искусственные концепции. Наверно, поэтому и споров вокруг них гораздо больше.
--
Я думал, ты огромный страшный Бажище,
А ты недоучка, крохотный Бажик...
Re[9]: Так в чем же принципиальные отличия ФП от ИП?
Здравствуйте, Draqon, Вы писали:
D>Это не левые процедуры. Это интерфейс объекта. D>То, что HANDLE файла и HANDLE консоли одинаково выглядят — это говорит о "типобезопасности", вернее, о её отсутствии. D>А не о том, что это не ООП.
если к "объектам" одного и того же типа — HANDLE — часть его "интерфейса" применять можно, а часть нельзя, то это по определению не интерфейс
Здравствуйте, SergH, Вы писали:
OE>>собственно и я о том же, было бы это ОПП это просто было бы невозможно SH>В скриптовых языках, которые как-будто вполне ООП, проверки идут в рантайме.
в скриптовых языках по другому просто нельзя сделать, что тут обсуждать
Здравствуйте, Odi$$ey, Вы писали:
OE>Здравствуйте, SergH, Вы писали:
OE>>>собственно и я о том же, было бы это ОПП это просто было бы невозможно SH>>В скриптовых языках, которые как-будто вполне ООП, проверки идут в рантайме.
OE>в скриптовых языках по другому просто нельзя сделать, что тут обсуждать
Ну дак кто мешает себе представить WinAPI как "скриптовый" интерфейс?
Никаких возражений по сути на это не последовало. Сдавайтесь сударь! Мы будем рады скрестить с вами шпаги в следующий раз А то начинается какое-то переливание из пустого в порожнее, отходы в сторону и т.п.
Здравствуйте, SergH, Вы писали:
OE>>в скриптовых языках по другому просто нельзя сделать, что тут обсуждать SH>Но это же не мешает им быть ОО? А тут почему-то мешает. Непорядок.
хорошо, спрошу так — когда ты пишешь в ООП стиле на С++ ты действительно делашь класс у которого метод aaaa() можно вызвать только если в конструктор передано "привет", метод bbb() только если в конструктор передано "пока", а метод сссс() есть, но только если его вызвать, в runtime все накроется медным тазом? Почему?
Ситуция практически один в один с типом HANDLE и методами его "интерфеса" SetConsoleCursorPosition, WriteFile и проч.
SH>Но честно говоря, я сейчас тебя вообще не понимаю. SH>Вроде Саша Шарыгин всё ну очень подробно описал и акценты расставил. Ну и я тоже немного тут http://www.rsdn.ru/Forum/Message.aspx?mid=2478206#2478206
Здравствуйте, Odi$$ey, Вы писали:
OE>Здравствуйте, SergH, Вы писали:
OE>>>в скриптовых языках по другому просто нельзя сделать, что тут обсуждать SH>>Но это же не мешает им быть ОО? А тут почему-то мешает. Непорядок.
OE>хорошо, спрошу так — когда ты пишешь в ООП стиле на С++ ты действительно делашь класс у которого метод aaaa() можно вызвать только если в конструктор передано "привет", метод bbb() только если в конструктор передано "пока", а метод сссс() есть, но только если его вызвать, в runtime все накроется медным тазом? Почему?
OE>Ситуция практически один в один с типом HANDLE и методами его "интерфеса" SetConsoleCursorPosition, WriteFile и проч.
Но это же не меняет сущности методов — они ОО. К тому же, попробуй их сделать нормальным ОО, когда у разных языков разные базовые объекты. Тут захочешь, а не сделаешь
Здравствуйте, Odi$$ey, Вы писали:
zE>хорошо, спрошу так — когда ты пишешь в ООП стиле на С++ ты действительно делашь класс у которого метод aaaa() можно вызвать только если в конструктор передано "привет", метод bbb() только если в конструктор передано "пока", а метод сссс() есть, но только если его вызвать, в runtime все накроется медным тазом? Почему?
OE>Ситуция практически один в один с типом HANDLE и методами его "интерфеса" SetConsoleCursorPosition, WriteFile и проч.
Через интерфейс handle тебе доступно несколько разных классов.
CreateFile это не конструктор, а фабрика классов.
При этом часть мотодов работает для всех хендлов — тут у нас полиморфизм.
А часть — не для всех — тут у нас типизация в рантайме.
OE>ну ты же первый был вот я с тебя и начал
Ты начал не с того сообщения. Я иногда слишком многословен и пишу лишнее. В данном случае, "программным" было сообщение про проектирование. Кстати, оно было раньше.
Здравствуйте, VladD2, Вы писали:
VD>>>Спроектировать большую систему в терминах модулей просто невозможно. Т>>А ничего, что самые большие системы именно в терминах модулей и проектировались?
VD>Примеры, плиз, в студию. Я лично вижу другие примеры. API Виндвос и Линукс имеют выраженную ООП архитектуру.
Возможно, имеются в виду какие-нибудь "адские" проекты DoD (а может, парижское метро).
А о чем спор, собственно?
Разве модульное программирование несовместимо с ООП?
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Здравствуйте, deniok, Вы писали:
D>С помощью такой аргументации можно доказать, что почти любая объёмная библиотека, написанная на С в 80-90е годы — ООП.
Не любая конечно. Например, стандартная библиотека С написана черти как.
Но в общем-то так оно и есть. ООП он стал востребован не потому, что его навязали. Это паттерн который был настолько востребован, что превратился в парадигму.
D>Например, ODBC. Хэндлы есть — инкапсуляция. Функции на хэндл вызываются — сообщения.
Ага. А что есть инкапсуляция как не основная концепция ООП?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Так в чем же принципиальные отличия ФП от ИП?
Пойми. ООП — это не формальное описание, а парадигма, то есть то как мы смотрим на решение задачи. Вот если бы смотрели на окно виндовс как на данные которые в результате операции преобразуются в новы еданные, то мы бы имели ФП. А так как мы смотрим на окно как на объект получающий сообщения и изменяющий свое состояние, то мы имеем дело с ООП.
И ООП, и ФП и любая другая прадигма могут эмулироваться практически на любом языке. Просто языки с непостредственной поддержкой парадигмы позволяют писать более чистый и понятный код.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Odi$$ey, Вы писали:
FDS>>И каков же будет результат работы у GetWindowText с handle от файла?
OE>собственно и я о том же, было бы это ОПП это просто было бы невозможно
Если пользоваться твоим ошибочным определением, то, например, ML (строготипизированны, типобезопасный, ФЯ) является ООЯ, так как не допускает (вообще) ошибок связанных с типами. А С++ не ООЯ, так как допускает (и легко) ошибки связанные стипами. На С++ я без труда могу вызвать любой методу не у того объекта.
FDS>>Опять же, подход ОО, но вот синтаксис не ОО. Разница ведь в том, что внутри, а не в синтаксисе.
OE>побарабану что там внутри, везде собственно одно и тоже — машинные коды, разница в том как это выглядит снаружи, для пользователя
По барабану что за машинный код там внутри. Хоть интерпретатор. Важно то как мы осознаем программу. Если в терминах объектов, то это ООП, пуст даже и эмулируемый на не ООЯ.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, SergH, Вы писали:
SH>В скриптовых языках, которые как-будто вполне ООП, проверки идут в рантайме. Т.е. у любого объекта можно вызвать любой метод. Да ещё и с любыми аргументами.
Ага. В питоне даже this, точнее его аналог — self передается явно.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, SergH, Вы писали:
OE>>winapi — ООП? хм..
SH>Важное слово выделено. Интерфейс Win API — реазультат объектно-ориентированного проектирования.
Кстати, когда проектировали NT (потомки которой сейчас и назваются Виндовс), то на полном серьезе рассматривали решение использовать С++ для написания этой ОС. Но отвергли это решение такак (гы-гы) в те времена считалось, что С++ создает неприемлемо большой оверхэд.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.