Чи важкий OOP, тому що це не природно?


86

Часто можна почути, що ООП природно відповідає тому, як люди думають про світ. Але я категорично не погоджуюся з цим твердженням: ми (або, принаймні, я) концептуалізуємо світ з точки зору взаємозв'язків між речами, з якими ми стикаємось, але в центрі уваги ООП розробляються окремі класи та їхні ієрархії.

Зауважте, що в повсякденному житті стосунки та дії існують здебільшого між об'єктами, які були б випадками непов'язаних класів в ООП. Прикладами таких стосунків є: "мій екран знаходиться вгорі таблиці"; «Я (людина) сиджу на стільці»; "машина в дорозі"; "Я набираю клавіатуру"; "кавоварка кипить воду", "текст відображається у вікні терміналу."

Ми думаємо з точки зору двовалентних (іноді тривалентних, як, наприклад, у "Я подарував вам квіти") дієслів, де дієслово - це дія (відношення), яка діє на два об'єкти, щоб створити певний результат / дію. Основна увага приділяється дії, і два (або три) [граматичні] об'єкти мають однакове значення.

Порівнюйте це з OOP, де спочатку потрібно знайти один об’єкт (іменник) і сказати йому, щоб виконати якусь дію над іншим об'єктом. Спосіб мислення зміщується з дій / дієслів, що діють на іменники, на іменники, що діють на іменники - це як би все сказано пасивним чи рефлексивним голосом, наприклад, "текст відображається у вікні терміналу". А може, "текст малює себе у вікні терміналу".

Не тільки фокус зміщується на іменники, але одному з іменників (назвемо це граматичний предмет) надається вища «важливість», ніж інша (граматичний об’єкт). Таким чином, ви повинні вирішити, чи буде сказати terminalWindow.show (someText) або someText.show (terminalWindow). Але навіщо обтяжувати людей такими тривіальними рішеннями без жодних операційних наслідків, коли дійсно означає шоу (terminalWindow, someText)? [Наслідки є оперативно незначними - в обох випадках текст відображається у вікні терміналу, але може бути дуже серйозним у дизайні ієрархій класів, і «неправильний» вибір може призвести до перекрученого та важкого у підтримці коду.]

Тому я б заперечував, що основний спосіб ведення ООП (на основі класу, одноразовий) є важким, оскільки він НЕУТРУДНИЙ і не відповідає тому, як люди думають про світ. Загальні методи з CLOS ближче до мого мислення, але, на жаль, це не дуже поширений підхід.

Зважаючи на ці проблеми, як / чому сталося так, що поточний спосіб ведення OOP став таким популярним? І що, якщо що, можна зробити, щоб детронувати це?


OOP призначений для "програмування", він призначений для задоволення компіляторів. це не спосіб будь-яким чином моделювати реальний світ. Під час викладання ООП звичайно використовувати приклади реального світу, такі як клас тварин та клас прямокутників, але це лише приклади для спрощення понять. На жаль, мова програмування та парадигми «трапляються» нееволюційно та ненауково. За нечисленними винятками, процес дизайну мови зазвичай є найкращою здогадкою для дітей!
NoChance

3
Я б не погоджувався з твердженням, що "зосередження діяльності ООП - це розробка окремих класів та їх ієрархій". оскільки майбі є в центрі уваги певної (-ої) реалізації OOP, але я, наприклад, виявив, що динамічні мови OOP зазвичай не мають великих ієрархій чи навіть класів. Що ж, визначення OOP може змінитися в майбутньому, є спроба змінити навіть Object one wcook.blogspot.com/2012/07/proposed-for-simplified-modern.html
Azder

1
OOP ідентифікує об'єкти в системі та будує класи на основі цих об'єктів. Не навпаки. Ось чому я також не погоджуюся з тим, що "основна увага ООП - це розробка окремих класів та їх ієрархій".
Раду Мурзеа


1
Я думаю, що це питання дуже суб'єктивне, і воно сповнене дивних припущень про ООП та що таке "реальний світ" та як люди думають про проблеми. І нарешті він навіть запитує: "А що, якщо що, можна зробити, щоб детронувати це?" що насправді показує, що ОП має дуже сильну думку з цього приводу. Якщо ви такі "релігійні" щодо парадигм програмування, я думаю, вам не потрібні відповіді ... ви вже знаєте, що хочете почути. Якби я знав про це питання, коли його вперше задавали, я, мабуть, проголосував би за його закриття ...
Саймон Леман

Відповіді:


97

OOP є неприродним для деяких проблем. Отже процедурні. Так функціонально. Я думаю, що у ООП є дві проблеми, які справді роблять це важким.

  1. Деякі люди діють так, що це єдиний вірний спосіб програмування, а всі інші парадигми помиляються. IMHO кожен повинен використовувати мову з декількома парадигмами та обрати найкращу парадигму для підпроблеми, над якою зараз працюють. Деякі частини коду матимуть стиль OO. Деякі будуть функціональними. Деякі матимуть прямий процедурний стиль. З досвідом стає очевидно, яка парадигма найкраща для чого:

    а. OO, як правило, найкраще, коли у вас є поведінка, сильно пов'язана зі станом, в якому вони діють, і точний характер стану є деталізацією реалізації, але його існування не може бути легко відібрати. Приклад: Класи колекцій.

    б. Процедура найкраща для тих випадків, коли у вас є маса поведінки, яка не сильно поєднана з якимись конкретними даними. Наприклад, можливо, вони працюють на примітивних типах даних. Тут найпростіше думати про поведінку та дані як про окремі сутності. Приклад: Числовий код.

    c. Функціонал найкраще, коли у вас є щось, що досить легко написати декларативно таким чином, що існування будь-якого стану взагалі є деталізацією реалізації, яку можна легко абстрагувати. Приклад: карта / зменшення паралелізму.

  2. OOP, як правило, показує свою корисність для великих проектів, коли дійсно необхідні добре складені фрагменти коду. У початкових проектах цього не буває занадто багато.


4
Я думаю, що важливим моментом у питанні було не те, чи є OOP природним, а чи основний підхід до ООП є найбільш природним підходом ООП. (Гарна відповідь все одно.)
Джорджіо

11
"OOP, як правило, показує свою корисність для великих проектів, коли дійсно необхідні добре інкапсульовані фрагменти коду.": Але це не специфічна властивість OOP, оскільки є хороші модульні концепції також для імперативних, функціональних, ... мов програмування .
Джорджіо

2
OOP дійсно на іншій осі процедурної / функціональної; в ньому розглядаються питання організації та інкапсуляції коду, а не способи опису операцій. (Ви завжди є партнером OOP з парадигмою виконання. Так, є функціональні мови OOP +.)
Дональні стипендіати

1
Чи не можна сказати, що OOP - це лише ті скриньки, до яких ми ставимо процедурні речі?
Ерік Реппен

В OOP ви все ще можете записати методи. Що робить OOP слабкішим за процедурне програмування?
Мерт Аккакая

48

ІМХО - це питання особистого смаку та способів мислення. У мене немає великих проблем з ОО.

Ми (або принаймні я) концептуалізуємо світ з точки зору взаємозв'язків між речами, з якими ми стикаємось, але в центрі уваги ООП розробляються окремі класи та їх ієрархії.

ІМХО це не зовсім так, хоча це може бути загальним сприйняттям. Алан Кей, винахідник терміна ОО, завжди наголошував на повідомленнях, що надсилаються між об'єктами, а не самими об'єктами. І повідомлення, принаймні для мене, позначають стосунки.

Зауважте, що в повсякденному житті стосунки та дії існують здебільшого між об'єктами, які були б випадками непов'язаних класів в ООП.

Якщо між об'єктами існує залежність, то вони пов'язані, за визначенням. В ОО ви можете виразити це залежністю асоціації / агрегації / використання між двома класами.

Ми думаємо з точки зору двовалентних (іноді тривалентних, як, наприклад, у "Я подарував вам квіти") дієслів, де дієслово - це дія (відношення), яка діє на два об'єкти, щоб створити певний результат / дію. Основна увага приділяється дії, і два (або три) [граматичні] об'єкти мають однакове значення.

Але вони все ще мають свої чітко визначені ролі в контексті: тема, предмет, дія тощо. "Я подарував вам квіти" або "Ви подарували мені квіти" - це не те саме (не кажучи вже про "Квіт подарував вам мене": -)

Порівнюйте це з OOP, де спочатку потрібно знайти один об’єкт (іменник) і сказати йому, щоб виконати якусь дію над іншим об'єктом. Спосіб мислення зміщується з дій / дієслів, що діють на іменники, на іменники, що діють на іменники - це як би все сказано пасивним чи рефлексивним голосом, наприклад, "текст відображається у вікні терміналу". А може, "текст малює себе у вікні терміналу".

Я не згоден з цим. ІМХО англійське речення "Білл, піди до біса" читається скоріше в програмному коді, bill.moveTo(hell)а не move(bill, hell). А перший насправді є більш аналогом оригінального активного голосу.

Таким чином, ви повинні вирішити, чи буде сказати terminalWindow.show (someText) або someText.show (terminalWindow)

Знову ж таки, не те саме, щоб попросити термінал показати якийсь текст, або попросити текст, щоб він показав термінал. ІМХО досить очевидно, який з них більш природний.

Зважаючи на ці проблеми, як / чому сталося так, що поточний спосіб ведення OOP став таким популярним?

Може тому, що більшість розробників ОО бачать ОО інакше, ніж ви?


15
+1 за безпосереднє згадування про повідомлення між об'єктами та їх важливість від Алана Кей
bunglestink

3
@zvrba, справді, були і інші піонери ОО, але це вже не в питанні цієї дискусії. "Найприродніше - просити показ тексту". - тепер ви використовуєте той самий пасивний голос, на який ви стверджували, що такий "неприродний" в OOP.
Péter Török

5
@zvrba, ти кажеш, що "завжди є" агент "[...], який робить якісь речі", проте протестує проти підходу ООС щодо ідентифікації та іменування цих агентів (об'єктів) та поводження з ними як першокласних громадян мовою . Для мене це частина моделювання проблемного домену - вам потрібно зробити цю роботу в будь-якому випадку, просто потім зіставити отриману модель домену для кодування по-іншому, залежно від того, ваша мова є OO чи ні.
Péter Török

6
@zvrba, не лише OO, а розробник / дизайнер вирішує питання про ролі та обов'язки різних об'єктів. Використання підходу OO може принести хороші чи погані моделі та конструкції домену, подібно до того, як за допомогою ножа можна отримати шматочок тонкого хліба або пальця, що кровоточить - все одно ми не звинувачуємо ніж, оскільки це лише інструмент. Зауважимо також, що поняття / об'єкти / агенти в моделі - це абстракції речей у реальному світі, і як такі завжди обмежені та спотворені, зосереджуючись лише на конкретних "цікавих" аспектах.
Péter Török

6
@zvrba, машина насправді не запускається за власним бажанням - так само, як Carоб'єкт буде start()лише тоді, коли його метод хтось явно закликає.
Péter Török

10

Деякі програмісти вважають, що OOD важко, тому що ці програмісти люблять думати про те, як вирішити проблему для комп'ютера, а не про те, як проблему слід вирішити.

... але в центрі уваги ООП розробляються окремі класи та їх ієрархії.

OOD НЕ з цього приводу. OOD - це з'ясування способів поведінки та взаємодії між собою.

Ми думаємо з точки зору двовалентних (іноді тривалентних, як, наприклад, у "Я подарував вам квіти") дієслів, де дієслово - це дія (відношення), яка діє на два об'єкти, щоб створити певний результат / дію. Основна увага приділяється дії, і два (або три) [граматичні] об'єкти мають однакове значення.

Орієнтація на ООД завжди на дію, де дії - це поведінка предметів. Об'єкти - ніщо без їх поведінки. Єдине обмеження об'єкта OOD полягає в тому, що все має бути зроблено чимось.

Я не вважаю, що цей діяч важливіший, ніж те, що він щось зробив.

Але навіщо обтяжувати людей такими тривіальними рішеннями без операційних наслідків, коли дійсно означає шоу (terminalWindow, someText)?

Для мене це те саме з різними позначеннями. Ви все ще повинні вирішити, хто є шоу-шоу та хто шоу-ей. Як тільки ви це знаєте, то рішення про ТОВ немає. Показати текст Windows -> Window.Show (текст).

Багато речей там (особливо у спадщині) говорить, що це ОО, коли його немає. Наприклад, існує величезна кількість коду C ++, який не реалізує фігуру OOD.

OOD легко, як тільки ви вийдете з розуму, що ви вирішуєте проблему для комп'ютерів. Ви вирішуєте проблеми для речей, які роблять речі.


10
Мені не подобається OOD саме тому, що я вважаю за краще думати, як вирішити проблему, період. Я не хочу думати про те, як перекласти природну мову проблемної області в чужорідний світ об'єктів, повідомлень, успадкування тощо. Я не хочу вигадувати ієрахічні таксономії там, де вони, природно, не існують. Я хочу описати проблему її природною мовою та вирішити її найпростішим можливим способом. І, до речі, світ складається не лише з "речей, які роблять речі". Ваш погляд на реальність надзвичайно вузький.
SK-логіка

7
@Matt Ellen, я пишу програми, які моделюють поведінку елементів, які не є "речами" і які не "роблять" жодних "речей". Будь-яке незмінне утворення нічого не робить. Будь-яка математична чиста функція нічого не робить - це лише відображення однієї множини в іншу, і цей світ здебільшого описується такими функціями. Будь-який логічний формалізм нічого не "робить". Так, OOD не допоможе мені, тому що я в змозі використовувати багато, набагато потужніші абстракції та моделі. Повернення до примітивної, обмеженої, обмежувальної ООС буде серйозно спричинити мене.
SK-логіка

2
@Matt Ellen, так, я хотів би побачити посилання, які підтримують такі дивні твердження, що світ краще розглядати як сукупність "речей, які роблять речі", або "об'єктів, які взаємодіють через повідомлення". Це абсолютно неприродно. Візьміть будь-яку наукову теорію (оскільки всі вони максимально наближені до моделювання реального світу, наскільки це можливо на цьому етапі), і спробуйте переписати її за допомогою своєї термінології. Результат буде незграбним і незграбним.
SK-логіка

4
@ Antonio2011a, не існує єдиної парадигми програмування чи моделювання, яка б ефективно охоплювала всі можливі проблемні області. OOP, функціонал, потік даних, логіка першого порядку, і все інше - всі вони є проблемними парадигмами, характерними для домену, і не більше того. Я лише виступаю за різноманітність та відкритий підхід до вирішення проблем. Звужувати своє мислення до єдиної парадигми - це просто нерозумно. Найбільш близьким до універсального підходу, що не обмежує вас однією смисловою рамкою, є en.wikipedia.org/wiki/Language-oriented_programming
SK-логіка

3
@Calmarius чому б ти спростив програмування для комп'ютерів? Це просто нерозумно. Людям доводиться робити більш важку роботу.
Метт Еллен

7

Можливо, я не в змозі зрозуміти, але:

Читаючи першу книгу про ООП (початок 90-х, тонкий посібник Борланда до Паскаля), я просто вразився своєю простотою та потенціалом. (Раніше я використовував мову Cobol, Fortran, Assembly і інші доісторичні речі.)

Для мене це досить зрозуміло: собака - тварина, тварина повинна їсти, моя собака - собака, тому вона повинна їсти ...

З іншого боку, саме програмування є неприродним (тобто штучним). Людська мова є штучною (не звинувачуйте мене, ми всі вивчили наші мови від інших, ніхто не знає людини, яка вигадала англійську мову) теж. На думку деяких вчених, розум людини формується мовою, яку він вивчив першим.

Я визнаю, деякі конструкції в сучасних мовах OO трохи незручні, але це еволюція.


1
Яка саме ваша робота була для вас перейти від кобола до фортран, потім до складання (та решти)?
Грак

1
Неправильний наказ. Насправді я починав з Basic, потім переїхав до Fortran, а потім до Assembly і Cobol (так, це правильний порядок: Асамблея спочатку). Першим комп’ютером у моєму житті був "гігантський" мейнфрейм, 256 КБ пам'яті, машинопис його консолі, годуючи її перфокартами, бо я був її оператором. Коли я досить піднявся, щоб стати системним програмістом, підозріла річ під назвою PC-AT приземлилася на мій стіл. Тож я занурився в GW-Basic, Turbo-Pascal, ... і так далі.
Неревар

1
Я не замислювався над цим. Більше до вашої роботи; тому що я не знаю багатьох людей (хто насправді), які мали справу з COBOL (орієнтованою на бізнес), fortran (наукова область), асемблером (більш орієнтованою на СС), а потім тими іншими. Проте вони професійні програмісти чи ні.
Грак

1
Ніякої таємниці: приєднатися до команд та проектів, де раніше було прийнято рішення про підхід до лагу. І якийсь нетривіальний рівень цікавості щодо інструментів, якими вони користуються.
Неревар

6

Одне, що ускладнило мене, - це думка, що OOP - про моделювання світу. Я подумав, що якщо я не знайшов цього права, щось може прийти і вкусити мене в дупу (річ чи правда, чи її немає). Я дуже усвідомлював проблеми, які роблять вигляд, що все є об'єктом чи сутністю. Це зробило мене дуже орієнтовним і недостатньо впевненим у програмуванні в OOP.

Потім я прочитав SICP і прийшов до нового розуміння, що мова йде дійсно про типи даних та контроль доступу до них. Усі проблеми, які я вирішив, були засновані на помилковій передумові, що в ООП ви моделюєте світ.

Я все ще дивуюся величезній складності, яку дала мені ця хибна передумова (і як я дозволяю собі це переконатися).


Дякую, що вказали на небезпеку спробувати моделювати світ.
Шон Макміллан

4

Так, сам OOP дуже неприродний - реальний світ не повністю складається з ієрархічних таксономій. Деякі невеликі його частини зроблені з цього матеріалу, і ці деталі - це єдині речі, які можна було б адекватно виразити з точки зору ОО. Все інше не може бути природно вписане в такий тривіальний і обмежений спосіб мислення. Дивіться природничі науки, дивіться, скільки різних математичних мов було винайдено, щоб висловити найпростішим або хоча б зрозумілим способом складність реального світу. І майже жоден з них не може бути легко перекладений мовою предметів і повідомлень.


5
Ну, це однаково вірно для будь-яких формальних позначень, які намагаються точно описати реальний світ.
Péter Török

1
@ Péter Török, саме мій погляд. Не існує єдиного формалізму, який би охоплював усе. Ви повинні використовувати їх усіх, у всій їхній страхітливій безлічі. І саме тому я вірю в мовно-орієнтоване програмування - воно дозволяє перейняти різні, часто несумісні формалізми в суцільну кодову сутність.
SK-логіка

1
Все можна класифікувати на ієрархічні таксономії. Трюк придумує схеми, які мають сенс. Часто бере участь багаторазове успадкування. Велика різниця між програмним забезпеченням і реальним світом полягає в тому, що в реальному світі нам часто доводиться робити висновки або відкривати схеми категоризації; в програмному забезпеченні ми їх винаходимо.
Калеб

1
Використовуючи такий термін, як "ієрархічна систематика", я думаю, що ви думаєте про спадок. Про наслідування насправді важко міркувати. Ось чому люди пропонують використовувати композицію над спадщиною.
Френк Ширар

1
@Frank: У реальному світі існує багато типів ієрархічних таксономій, успадкування яких - лише одна. Для цього все потрібні кращі інструменти, ніж ООП (наприклад, онтологічні міркування) і спричиняли проблеми для філософів тисячоліттями…
Дональд стипендіатів

4

Ми (або принаймні я) концептуалізуємо світ з точки зору взаємозв'язків між речами, з якими ми стикаємось, але в центрі уваги ООП розробляються окремі класи та їх ієрархії.

Ви починаєте з (ІМО) помилкового передумови. Зв'язки між об'єктами, мабуть, важливіші, ніж самі об'єкти. Саме відносини дають об'єктно-орієнтовану програмну структуру. Спадкове відношення між класами, безумовно, важливе, оскільки клас об'єкта визначає, що може зробити цей об'єкт . Але саме відносини між окремими об'єктами визначають, що об'єкт насправді робить у межах, визначених класом, а отже, як поводиться програма.

Об'єктно-орієнтована парадигма спочатку може бути складною не тому, що складно придумати нові категорії об'єктів, а тому, що складно передбачити графік об'єктів і зрозуміти, якими мають бути зв’язки між ними, особливо коли у вас немає спосіб описати ці стосунки. Ось чому дизайнерські моделі настільки корисні. Шаблони дизайну майже повністю стосуються відносин між об'єктами. Шаблони дають нам і ті будівельні блоки, які ми можемо використовувати для проектування відносин об'єктів на більш високому рівні, і мову, яку ми можемо використовувати для опису цих відносин.

Те саме стосується творчих сфер, які працюють у фізичному світі. Будь-хто міг зібрати купу кімнат і назвати це спорудою. Кімнати можуть бути навіть повністю обладнані найсучаснішими приміщеннями, але це не приносить будівельних робіт. Завдання архітектора - оптимізувати відносини між цими кімнатами відповідно до потреб людей, які користуються цими кімнатами, та оточення будівлі. Правильні відносини - це те, що робить будівельну роботу як з функціональної, так і з естетичної точки зору.

Якщо у вас виникають проблеми з звиканням до ООП, я б радив вам подумати більше про те, як ваші об’єкти поєднуються між собою та як влаштовані їхні обов'язки. Якщо ви ще цього не зробили, читайте про шаблони дизайну - ви, ймовірно, зрозумієте, що ви вже бачили візерунки, про які читали, але даючи їм назви, ви зможете бачити не лише дерева, а й підставки, перегородки, зарості, ліси, гаї, ліси та зрештою ліси.


3

Це лише частина того, що не так з OOP.

По суті, функції стають громадянами другого класу, і це погано.

Сучасні мови (рубін / пітон) не страждають від цієї проблеми і надають функції як об'єкти першого класу, а також дозволяють створювати програми, не будуючи жодної ієрархії класів.


OOP мені здається дуже природним, насправді мені важко думати про завдання програмування будь-яким іншим способом. І все-таки з роками я зрозумів, що ООП має тенденцію перебільшувати іменники над дієсловами. Ця сканда з 2006 року допомогла мені зрозуміти цю відмінність: steve-yegge.blogspot.com/2006/03/…
Jim In Texas

3

OOP не важкий. Що ускладнює добре використання, це неглибоке розуміння того, для чого це добре, коли програмісти чують випадкові сентенції і повторюють їх собі під ніс, щоб отримати благословення божественної банди чотирьох, блаженного Мартіна Фаулера, або кого б вони не читали.


3

ЗДОРОВАНО

Перш за все, я хотів би сказати, що я ніколи не знаходив OOP важким або складнішим за інші парадигми програмування. Програмування за своєю суттю важке, оскільки воно намагається вирішити проблеми з реального світу, а реальний світ надзвичайно складний. З іншого боку, читаючи це питання, я запитав себе: чи ООП "природніший", ніж інші парадигми? І тому ефективніше?

Я колись знайшов статтю (хотів би, щоб я її знову знайшов, щоб я міг розмістити її як посилання) про порівняльне дослідження між імперативним програмуванням (IP) та об'єктно-орієнтованим програмуванням (OOP). Вони в основному вимірювали продуктивність професійних програмістів, які використовують IP та OOP в різних проектах, і в результаті було те, що вони не бачили великих відмінностей. Отже, твердження полягало в тому, що не було великої різниці в продуктивності між двома групами, і що на справді розраховується досвід.

З іншого боку, прихильники об'єктної орієнтації стверджують, що, хоча під час ранньої розробки системи ООП може зайняти навіть більше часу, ніж імператив, в кінцевому рахунку код легше підтримувати і розширювати через тісну інтеграцію даних і операції.

Я працював переважно з мовами OOP (C ++, Java), але часто відчуваю, що можу бути настільки продуктивним, використовуючи Pascal або Ada, хоча я ніколи не пробував їх для великих проектів.

Порівнюйте це з OOP, де спочатку потрібно знайти один об’єкт (іменник) і сказати йому, щоб виконати якусь дію над іншим об'єктом.

[вирізати]

Тому я б заперечував, що основний спосіб ведення ООП (на основі класу, одноразовий) є важким, оскільки він НЕУТРУДНИЙ і не відповідає тому, як люди думають про світ. Загальні методи з CLOS ближче до мого мислення, але, на жаль, це не дуже поширений підхід.

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

Мені відомі інші пропозиції OO, де кілька об'єктів отримують повідомлення замість лише одного, тобто декілька об’єктів відіграють симетричну роль при отриманні повідомлення. Так, це здається мені більш загальним і, можливо, більш природним (менш обмежуючим) підходом до ООП.

З іншого боку, "багаторазове відправлення" можна легко імітувати за допомогою "разової відправки", а "одиничну відправлення" легше реалізувати. Можливо, це одна з причин, чому "багаторазова відправка" не стала мейнстрімом.


3

Перестаньте шукати виключно парадигму OOP і спробуйте трохи JavaScript.

В даний час у мене є щось із розробленої схеми, де мої об’єкти інтерфейсу працюють в інтерфейсі, керованому подією. Тобто, у мене з’явиться те, що виглядає як типовий публічний метод, який при запуску призводить до внутрішньо визначеної дії. Але коли його звільняють, насправді відбувається те, що я запускаю подію на самому об'єкті, і заздалегідь визначений обробник всередині цього об'єкта відповідає. Цю подію та об'єкт події, до яких можна приєднати властивості, передані будь-якому іншому слухачеві, може почути все, що хочете слухати. Ви можете слухати об'єкт безпосередньо, або взагалі слухати для цього типу події (події також спрацьовують на загальному об'єкті, які можуть слухати всі об’єкти, побудовані на заводі). Так ось, наприклад, у мене є комбіноване поле, де ви вибираєте новий елемент зі спадного списку.

Якщо ви хочете, (і я здивовано виявив, що я зазвичай не хочу - це питання розбірливості, коли ви не бачите, звідки подія береться), ви можете виконати повну розв’язку об'єкта та встановити контекст через переданий об'єкт події. Незважаючи на те, ви все ще ухиляєтесь від однієї відправки, маючи можливість зареєструвати декілька відповідей.

Але я не роблю цього тільки з OOP, і JS навіть не є належним чином OOP за деякими визначеннями, які я вважаю веселими. На мою думку, для вищих рівнів розвитку додатків, на мою думку, є можливість привласнити парадигму до того, що працює для вашої ситуації, і ми можемо наслідувати класи, якщо ми піклуємося про це. Але в цьому випадку я змішую аспекти функціональності (передача обробників навколо) з OOP.

Що ще важливіше, те, що я маю, відчуває себе досить сильним. Я не думаю про те, що один об’єкт діє на інший. Я в основному вирішую, які саме об’єкти хвилюють, надаю їм інструменти, необхідні для розбирання речей, і просто опускаю їх у змішувач і даю їм реагувати один на одного.

Тож я здогадуюсь, що я говорю це: це не проблема вимикання. Це суміш і поєднання. Проблема полягає в мовах і хижах, які хочуть, щоб ви повірили, що це одна річ uber alles. Як може, наприклад, молодший java dev справді оцінити OOP, якщо вони думають, що вони завжди роблять це правильно за замовчуванням?


2

Те, як мені це було пояснено, було з тостером та машиною. У обох є пружини, тож у вас був би об'єкт "пружини", і вони були б різного розміру, міцності і будь-якого іншого, але вони обидва були б "пружинами", а потім поширювали цю метафору на машину, якби у вас було багато коліс (Колеса, очевидно, плюс кермо, тощо), і це мало багато сенсу.

Потім ви можете розглядати програму як перелік об’єктів, і візуалізувати її набагато простіше, ніж "Це список речей, які роблять речі, тому це не такий список інструкцій, який ви бачили раніше"

Я думаю, що справжня проблема з ООП полягає в тому, як це пояснюється людям. Часто (в моїх універсальних класах) я бачу, як це пояснюється, кажучи "йдеться про багато класів, які роблять дрібниці, і ви можете створювати з цього об'єкти", і все це бентежить багатьох людей, тому що він використовує те, що по суті є абстрактним терміни для пояснення цих понять, а не конкретні ідеї, які люди зрозуміли, коли їм було 5 років, граючи з лего.


2
Пружини бувають у мільйонних формах, всі вони виконують подібні функції . Я б сказав, що це прекрасний приклад функціонального програмування.
l0b0

2

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


Але чи класифікуєте ви, чи мають деякі об'єкти спільні ознаки чи спільну поведінку? Чи все, що має ім’я та прізвище людини? Чи все, що гуляє тварина?
zvrba

Що стосується категоризації, то здатність виконувати певну поведінку є атрибутом. Зебри та коні можуть розводити, але потомство - гібрид. Дуже важко передбачити цей результат, грунтуючись на функції спарювання, якщо ви не знаєте, що вони не є одним і тим же видом.
JeffO

1
@zvrba: Моя відповідь на питання, поставлене в коментарі, таке it doesn't matter. Все, що має ім’я та прізвище - це людина кожної програми, яка піклується лише про людей. Для будь-якої програми, яка не знає людей чи людей, це не є людиною IHasNameAndSurname. Об'єктам потрібно лише вирішити проблему.
Том Ш

@Jeff O Навіть у одного виду / породи / популяції є варіації і немає ідеального (істотного) прикладу. Так, так OO не є такою, якою є насправді природа, але це добре підходить до того, як люди природно думають.
Том Хотін - тайклін

2

Я думаю, що деякі труднощі виникають, коли люди намагаються використовувати OOP для реальності. Всім відомо, що автомобіль має чотири колеса та двигун. Всім відомо , що автомобілі можуть Start(), Move()і SoundHorn().

Світло клацнуло в моїй голові, коли я зрозумів, що повинен припиняти намагання робити це постійно. Об'єкт - це не те, з чим він має ім'я. Об'єкт є (тобто повинен бути) достатньо деталізованим розділом даних, що стосуються обсягу проблеми. Це oughtмати саме те , що рішення проблеми не потребує в цьому не мати, не більше і не менше. Якщо створення об'єкта, відповідального за деяку поведінку, призводить до того, що більше рядків коду, ніж однакова поведінка, є роботою якоїсь неясного третьої сторони (дехто може назвати це "полтергейстом"), то полтергейст заробляє свої фішки.


1

Для управління складністю нам потрібно згрупувати функціональність в модулі, і це взагалі складна проблема. Це як колишня приказка про капіталізм, OOP - це найгірша система організації програмного забезпечення там, за винятком всього іншого, що ми намагалися.

Причина, по якій ми групуємо взаємодію всередині іменників, хоча часто існує неоднозначність щодо того, з ким з двох іменників згрупувати її, полягає в тому, що кількість іменників, як правило, працює з класами керованого розміру, тоді як групування за дієсловами має тенденцію або до виробництва дуже малі групи, як одноразові, або дуже великі групи для такої функції, як шоу . Повторне використання таких понять, як успадкування, також відбувається набагато простіше при групуванні за іменниками.

Крім того, питання щодо вирішення питання про те, чи виставити шоу з вікном або з текстом, практично завжди набагато зрозуміліше на практиці, ніж теоретично. Наприклад, майже всі групи інструментів GUI додають разом з контейнером, але показують за допомогою віджета. Якщо ви спробуєте написати код іншим способом, причина стає очевидною досить швидко, хоча думка про це абстрактно два способи здаються взаємозамінними.


2
Ви коли-небудь бачили правильну модульну систему? Як ви можете сказати, що OOP - найкраще з наявних? Модулі SML набагато, набагато потужніші. Але навіть пакетів Ada достатньо для більшості випадків, навіть без крихітного натяку на OOP.
SK-логіка

@ SK-логіка, я думаю, ви зациклюєтесь на надто точних визначеннях. Під OOP я не маю на увазі класи , я маю на увазі логічне групування «дієслів» за «іменниками», над якими вони діють, і можливість повторного використання та спеціалізації цих дієслів на основі конкретних іменників, над якими вони діють. Заняття є найбільш відомою реалізацією цього, але це не єдина реалізація. Я визнаю незнання модулів SML, але перший приклад, який я побачив, коли я його шукав, - це реалізація черги, яка могла виникнути з будь-якої книги дизайну OO із змінами синтаксису, щоб зробити її функціональною.
Карл Білефельдт

просто не було б справедливо давати нещасній ООП занадто багато кредитів за те, що їй не належить. Модулі - чудовий винахід. Модулі першого класу - фантастичні. Але ООП взагалі нічого спільного з ними не має. Деякі мови OOP прийняли деякі функції модуля (особливо - простори імен), але модулі набагато загальніші та потужніші поняття, ніж класи. Ви сказали, що заняття "найкращі", що далеко не правда. Першокласні модулі набагато краще. І, звичайно, типові системи набагато ширші та глибші, ніж просто ОО з його підгрунтністю.
SK-логіка

1
"Це як колишня приказка про капіталізм. OOP - це найгірша система організації програмного забезпечення там, за винятком всього іншого, що ми намагалися.": Можливо, ми не намагалися досить довго. :-)
Джорджіо

1
Я думаю, ти маєш на увазі "демократія": quotationspage.com/quote/364.html
nicodemus13

1

Ні . Існує кілька способів вирішити проблему за допомогою програмування: функціональний, процедурний, логічний, ООП та інші.

У реальному світі іноді люди використовують функціональну парадигму, а іноді ми використовуємо процедурну парадигму тощо. І іноді ми змішувались. І врешті-решт ми представляємо їх як певний стиль чи парадигму програмування.

Існує також парадигма "все - це список або пункт", що використовується в LISP. Мені подобається згадувати як про річну функціональну програмування . PHP використовує це в асоціативних масивах.

Парадигми OOP та "Все є списком або пунктом" вважають 2 ЗНАЧЕННЯ ПРИРОДНИХ стилів програмування, як я пам’ятаю в деяких класах штучного інтелекту.

Мені здається дивним: "ООП не є природним", можливо, те, як ви дізнаєтесь, або те, як вас вчили про ООП, невірно, але не сам OOP.


1

Зважаючи на ці проблеми, як / чому сталося так, що поточний спосіб ведення OOP став таким популярним? І що, якщо що, можна зробити, щоб детронувати це?

OOP став популярним, оскільки пропонує інструменти для організації вашої програми на більш високому рівні абстракції, ніж популярні процедурні мови, які передували їй. Було також порівняно легко скласти мову, яка мала процедурну структуру всередині методів та об'єктно-орієнтовану структуру, що їх оточувала. Це дозволило програмістам, які вже вміли процедурно програмувати, обирати принципи ОО один за одним. Це також призвело до безлічі програм, призначених лише для OO-імені, які були процедурними програмами, загорнутими в клас або два.

Щоб детронувати OO, побудуйте мову, яка спрощує поступовий перехід від того, що сьогодні знає більшість програмістів (переважно процедурних, з невеликою кількістю OO) до бажаної парадигми. Переконайтеся, що він надає зручні API для виконання загальних завдань і добре просуває їх. Незабаром люди роблять програми лише для X-in-name на вашій мові. Тоді ви можете розраховувати, що люди пройдуть роки та роки, аби насправді зробити X.


ОП не стверджує, що ОО в цілому погано і його слід усунути, але "поточний спосіб ведення ООП" не є самим природним (порівняно з "багаторазовим відправленням").
Джорджіо

ОП також здається надмірно орієнтованою на визначення ієрархії типів, де найкращі програми ОО зазвичай більше покладаються на інтерфейси та композицію. Якщо багаторазове відправлення - це X, то запорука мови, яка дозволяє людям поступово вивчати навички, пов'язані з багаторазовою відправленням, все ще є ключем до зміни середовища.
Шон Макміллан

1

Я думаю, що у мов OOP та OOP теж є проблеми.

Якщо це правильно зрозуміти, OOP - це чорні скриньки (об’єкти), на яких є кнопки, які можна натискати (методи). Заняття якраз існують, щоб допомогти впорядкувати ці чорні скриньки.

Одна з проблем - коли програміст кладе кнопки на неправильний об'єкт. Термінал не може показувати текст сам по собі, текст не може відображати себе в терміналі. Компонент менеджера вікон операційної системи, який може це зробити. Вікно та текст терміналу - лише пасивна сутність. Але якщо ми думаємо таким чином, ми розуміємо, що більшість сутностей - це пасивні речі, і у нас буде лише дуже мало об’єктів, які насправді роблять що-небудь (або просто один: комп'ютер ). Дійсно, коли ви використовуєте C, ви організовуєте його в модулі, ці модулі представляють мало об’єктів.

Ще один момент полягає в тому, що комп'ютер просто виконує інструкції послідовно. Припустимо, у вас є об’єкт VCRі Televisionяк ви відтворювали відео? Ви, напевно, пишете щось подібне:

connect(television, vcr);
vcr.turnOn();
television.turnOn();
insert(vcr, yourFavoriteCasette);
vcr.play();
while (vcr.isPlaying()) {} // Wait while the VCR is playing the casette.
vcr.eject();
vcr.turnOff();
television.turnOff();

Це було б дуже просто, але для цього вам знадобляться принаймні 3 процесори ( або процеси ): один грає вашу роль, другий - відеомагнітофон, третій - телевізор. Але зазвичай у вас є лише одне ядро ​​(принаймні, недостатньо для всіх ваших об'єктів). У коледжі багато моїх однокласників не розуміли, чому GUI замерзає, коли кнопка робить дорогу операцію.

Тому я думаю, що об'єктно-орієнтована конструкція може досить добре описати світ, але це не найкраща абстракція для комп'ютера.


0

Погляньте на DCI (дані, контекст та взаємодію), винайдені винахідником схеми MVC.

Мета DCI (цитується з Вікіпедії):

  • Надайте системній поведінці статус першого класу, над об'єктами (іменниками).
  • Чітко відокремити код для швидко змінюється поведінки системи (що робить система) від коду для повільної зміни знань про домен (що таке система), а не поєднувати обидва в одному інтерфейсі класу.
  • Підтримувати об’єктний стиль мислення, що ближче до ментальних моделей людей, а не класового стилю мислення.

Ось гарна стаття авторів, і ось невеликий приклад реалізації (.NET), якщо ви хочете побачити якийсь код. Це набагато простіше, ніж це може звучати, і відчувається дуже природно.


0

Часто можна почути, що ООП природно відповідає тому, як люди думають про світ. Але я категорично не згоден з цим твердженням (...)

Оскільки вона десятиліттями євангелізується в книгах та інших місцях, я теж не погоджуюся з цим. Тим не менш, я думаю, що саме так вирішили саме Нігаард і Дал, і я думаю, що вони зосереджувались на тому, як легше було подумати над створенням симуляцій порівняно з альтернативами часу.

(...), але в центрі уваги ООП розробляються окремі класи та їхні ієрархії.

Це твердження потрапляє на розумну територію з огляду на те, наскільки популярні неправильні уявлення про ООП та наскільки чутливі ОО до визначення. У мене більше десяти років в цій галузі, займаючись як галузевою роботою, так і академічними дослідженнями прогр. Мови, і я можу вам сказати, що я багато років навчався "мейнстріму ОО", тому що я почав помічати, наскільки він відрізняється (і неповноцінним) від того, на що прагнули попередні творці. Для сучасного, сучасного поводження з цим предметом я б посилався на нещодавні зусилля У. Кука:

"Пропозиція щодо спрощених та сучасних визначень" Об'єкт "та" Орієнтоване на об'єкт " http://wcook.blogspot.com.br/2012/07/proposed-for-simplified-modern.html

Зважаючи на ці проблеми, як / чому сталося так, що поточний спосіб ведення OOP став таким популярним?

Можливо, з тієї ж причини, що стали популярними клавіатури QWERTY, або ж стала причиною популярності операційна система DOS. Речі просто їздять на популярних транспортних засобах, незважаючи на їх властивості, і стають популярними самі. І іноді подібні, але гірші версії чогось приймаються як реальна річ.

І що, якщо що, можна зробити, щоб детронувати це?

Напишіть програму, використовуючи чудовий підхід. Напишіть ту ж програму, використовуючи підхід OO. Показати перший має кращі властивості, ніж останній у кожному важливому аспекті (як властивості самої системи, так і технічні властивості). Покажіть, що обрана програма є релевантною, а запропонований підхід підтримує високу якість властивостей, якщо застосовуватись до інших програм. Будьте суворі у своєму аналізі та використовуйте точні та прийняті визначення, коли це необхідно.

Нарешті, поділіться своїми висновками з нами.


-1

Візьміть Java: об'єкти є своєрідним вузьким місцем абстракції, більшість "речей" є або строго підкомпонентами об'єктів, або використовують об'єкти як їх підкомпоненти. Об'єкти повинні бути достатньо багатоцільовими для цілого шару абстрагування між цими двома типами речей - муті-призначення означає, що немає жодної метафори, яку вони втілюють. Зокрема, Java робить об'єкти (& класи) єдиним шаром, через який ви викликаєте / відправляєте код. Така кількість речей, які втілюють об'єкти, робить їх, чесно кажучи, занадто складними. Будь-який корисний опис їх повинен бути обмежений певною спеціалізованою або обмеженою формою.

Ієрархії успадкування та інтерфейсу - це "речі", які використовують об'єкти як підкомпоненти. Це один спеціалізований спосіб опису предметів, а не спосіб отримати загальне розуміння об'єктів.

Можна сказати, що "об'єкти" мають чи є багато речей, оскільки вони є багатоцільовою абстракцією, що є більш-менш універсальною в "OO Langauge". Якщо вони використовуються, щоб містити локальний стан, що змінюється, або для доступу до якогось зовнішнього стану світу, вони дуже схожі на "іменник".

Навпаки, об’єкт, який представляє процес, наприклад, "зашифрувати" або "стиснути" або "сортувати", виглядає як "дієслово".

Деякі об'єкти використовуються для ролі простору імен, наприклад, місце для розміщення "статичної" функції на Java.

Я схильний погодитися з аргументом того, що Java занадто важка для викликів об'єктного методу, з відправленням на об'єкт. Це, мабуть, тому, що я віддаю перевагу класам типів Haskell для контролю відправки. Це обмеження для відправки і є особливістю Java, але не більшості мов або навіть більшості мов OO.


-3

Я був свідком та брав участь у багатьох інтернет-дебатах про ООП. Прихильники ООП зазвичай не знають, як написати належний процедурний код. Можна написати процедурний код, який є високомодульним. Можна розділити код і дані та переконатися, що функції можуть записувати лише до власного сховища даних. Реалізувати концепцію спадкування можна за допомогою процесуального кодексу. Що ще важливіше, процедурний код тонший, швидший і простіший налагодження.

Якщо ви будуєте однофайлові модулі зі строгими умовами іменування, процедурний код простіше писати та підтримувати, ніж OO, і він буде робити те саме чи більше і швидше. І не забувайте, що коли ваша програма працює, це завжди є процедурним незалежно від того, скільки класів міститься у вашому сценарії.

Тоді ви маєте випуск мов на зразок PHP, які насправді не орієнтовані на об'єкти і покладаються на хаки, щоб підробити речі, такі як багаторазове успадкування. Великі кадри, які впливають на напрямок мови, перетворили PHP на печворк непослідовних правил, які стали занадто великими для того, що він спочатку задумав. Коли я бачу, як розробники пишуть величезні шаблонні класи для того, що було призначено як мова для процедурних шаблонів, я не можу не посміхнутися.

Якщо ви порівнюєте правильно написаний код коду з погано написаним процесуальним кодом, то ви завжди прийдете до неправильного висновку. Дуже мало проектів гарантує об'єктно-орієнтований дизайн. Якщо ви IBM і керуєте величезним проектом, який потрібно підтримувати роками декількома розробниками, перейдіть до об'єктно-орієнтованого. Якщо ви пишете невеликий блог чи торговий веб-сайт для клієнта, подумайте двічі.

Відповісти на початкове запитання, OOP важко, оскільки він не вирішує дилеми програмування в реальному житті, не вдаючись до рішень, які в 100 разів складніші, ніж повинні бути. Одним з найпотужніших рішень багатьох проблем програмування є розумне використання глобальних даних. І все ж випускники університетів нової хвилі скажуть вам, що це велика ні-ні. Загальнодоступні дані небезпечні лише в тому випадку, якщо ви незграбний кролик із програмування. Якщо у вас є чіткий набір правил і належні умови узгодження імен, ви можете піти від того, щоб усі ваші дані були глобальними.

Будь-яка об’єктна орієнтована програмістка повинна бути обов'язковою вимогою знати, як написати шахматну програму в асемблері для максимальної пам'яті 16K. Потім вони б навчилися підстригати жир, скорочувати лінь і генерувати геніальні рішення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.