Чому не існує послідовного визначення суттєвих понять для ООП?


12

Я дуже новачок у програмуванні та трохи заплутаний у читанні \ слуханні різних конвенцій з різних джерел:

Чи об'єктно-орієнтоване програмування має 4 або 5 понять?

Як новачок я розумію, що це 5 понять:

  • Абстракція
  • Спадщина
  • Інкапсуляція
  • Поліморфізм
  • Модульність

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


7
Можливо, тому, що це не так, як математика (деякі поняття в CS є, але я думаю, що OOP не належить до цієї категорії), тому для цього немає суворих визначень. Так, наприклад, наскільки важливою є «модульність»? Це насправді настільки особливе для OOP, що ми мусимо його згадати чи це буде щось таке, що відбувається саме собою, якщо правильно застосувати інші чотири? Деякі списки додають "ієрархію", але це насправді щось зайве або просто випливає із спадщини та поліморфізму?
thorsten müller

6
Слово ради: Як зовсім новий програміст, ви не повинні так зациклюватися на розумінні термінології та теорії. Спершу зберіть трохи практичного досвіду програмування, і вийде набагато очевидніше, про що говорять ці люди.
Філіп

9
Інша справа, що ООП змінюється з часом. Велика увага на початку C ++ днів (я знаю, що ООП йде далі, ніж це) була приділена спадщині та поліморфізму. Сьогодні увага значно більше приділяється абстракції та інкапсуляції.
Бент

3
Деякі цікаві дискусії про недостатню точність у визначенні ОО можна знайти тут: c2.com/cgi/wiki?NobodyAgreesOnWhatOoIs
MichelHenrich

Відповіді:


26

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

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


12

Чи об'єктно-орієнтоване програмування містить 5 або 4 компоненти?

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

Як новачок я розумію, що це 5 компонентів:

Абстракція, спадкування, інкапсуляція, поліморфізм та модульність?

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

Абстракція, інкапсуляція та модульність менше пов'язані з кодом і більше про те, як ви дивитесь на проблему, про те, як ви намагаєтесь зрозуміти цю проблему, і про те, як ви розробляєте та структуруєте рішення в коді.

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

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

Наприклад, класичні приклади часто посилаються на сутності , такі як Dog, Cat, Elephant, Seagull, Sharkі т.д. потрапили в «ОО» часто дивляться на такі приклади і відразу ж думати : «О, мені потрібен базовий об'єкт під назвою Animal" , і вони навіть можуть в кінцевому підсумку з іншими проміжних утворень, таких як Mammalі Amphibianз чіткою спадковою спадщиною, з різними ознаками у кожному.

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

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

Загалом, багато вашого розуміння зійде з досвіду. Ті поняття, яких ви вивчили до цього часу, - це гарний початок, є більше понять, які вам потрібно буде вивчити на цьому шляху (наприклад, принципи "Твердий" та "Сухий"), і вам потрібно буде витратити тривалий час на вкладення теорія на практиці з реальними дуже складними проблемами, перш ніж все, швидше за все, "натисне" на місце.


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

10

Термін "Орієнтація на об'єкти" був введений доктором Аланом Кей, тому він є авторитетним джерелом того, що це означає, і він визначає це таким чином :

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

Розберемо це:

  • обмін повідомленнями ("віртуальний метод відправки", якщо ви не знайомі з Smalltalk)
  • державний процес повинен бути
    • локально зберігається
    • захищені
    • приховано
  • крайнє пізнє зв’язування всіх речей

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

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

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

Велика ідея - це "обмін повідомленнями" - саме про це і полягає ядро ​​Smalltalk / Squeak (і це те, що ніколи не було завершено в нашій фазі Xerox PARC). У японців є невелике слово - ma - для "того, що знаходиться між ними" - можливо, найближчий англійський еквівалент "interstitial". Ключове значення у створенні чудових та розростаючих систем - це набагато більше, щоб розробити, як його модулі спілкуються, а не якими мають бути їх внутрішні властивості та поведінка. Подумайте про Інтернет - щоб жити, він (а) повинен дозволити безліч різних ідей та реалізацій, що виходять за межі будь-якого єдиного стандарту, та (b) дозволяти різного ступеня безпечної взаємодії між цими ідеями.

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

Повідомлення є основним для ОО як метафори, так і як механізму.

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

Більш "сучасним" терміном "обмін повідомленнями" є "динамічне відправлення методу" або "віртуальний виклик методу", але це втрачає метафору і фокусується на механізмі.

Отже, є два варіанти визначення визначення Алана Кей: якщо ви дивитесь на це самостійно, ви можете помітити, що повідомлення в основному є запізненням виклику процедури, а пізнє зв'язування передбачає інкапсуляцію, тому ми можемо зробити висновок, що №1 і №2 насправді є надлишковими, і OO - все про пізнє зв’язування.

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

Подібні пункти також в On Розуміння абстракції даних, Revisited по Вільям Р. Кук , а також його пропозиція щодо спрощення, сучасні визначення «об'єкта» і «об'єктно - орієнтованого» .

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

У Smalltalk-72 навіть об’єктів не було! Були лише потоки повідомлень, які були розібрані, переписані та перепрограні. Спочатку з'явилися методи (стандартні способи розбору та перенаправлення потоків повідомлень), пізніше з'явилися об'єкти (групування методів, які поділяють деякий приватний стан). Успадкування з'явилося набагато пізніше, і заняття були запроваджені лише як спосіб підтримки спадщини. Якби дослідницька група Кей вже знала про прототипи, вони, ймовірно, ніколи б не вводили заняття в першу чергу.

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

Отже: за словами Алана Кей, OO - все про обмін повідомленнями. За словами Вільяма Кука, OO - це все про динамічне відправлення методу (це дійсно те саме). За словами Бенджаміна Пірса, все стосується відкритої рекурсії, що в основному означає, що самонавіювання динамічно вирішується (або, принаймні, це спосіб задуматися) або, іншими словами, повідомленнями.

Як бачите, людина, яка ввела термін "ОО", має досить метафізичний погляд на об'єкти, Кук має досить прагматичний погляд, а Пірс - дуже суворий математичний погляд. Але важливо: філософ, прагматик і теоретик всі згодні! Повідомлення - це один стовп ОО. Період.

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


1
@DavidArno Ваш коментар зовсім не конструктивний. Сам Алан Кей стверджує, що ввів для цього поняття термін "об'єкт" (хоча, я думаю, не саме поняття). Якщо ви збираєтесь суперечити відомим авторитетом з цього приводу, принаймні напишіть більш конструктивний коментар.
Андрес Ф.

1
@DavidArno Крім того, чи є нижченаведена ваша? Тож хтось знайшов час, щоб написати вичерпний перелік різних поглядів, відомих експертів, на те, що означає OOP, і ви спростували це, оскільки ви не згодні з одним пропозицією? Добре.
Андрес Ф.

2
@AndresF. Цю відповідь можна підсумувати як "існують дві школи, хоча Алан Кей і всі інші. Оскільки колишній вигадав термін, він автоматично має рацію, і кожен, хто не погоджується з ним, помиляється". Це заклик до відповіді на помилковість влади. Тим самим потік.
Девід Арно

2
Власне, цю відповідь можна підсумувати, оскільки "є три школи думки, що виходять з трьох абсолютно різних точок зору, і ніхто ні з ким не погоджується, насправді вони всі згодні". Лінгвістичний рецептурист сказав, що Алан Кей винайшов цей термін, він може сказати, що він означає, і він каже, що це означає обмін повідомленнями. Лінгвістичний дескриптивіст сказав би: ні, Алан Кей нічого не може сказати, ми повинні подивитися, як насправді використовується цей термін , і це робив Кук: він вивчав, які мови зазвичай називають ОО (Java, C ++ , C # та ін.) Мають спільне, і він знайшов
Йорг W Міттаг

3
одне: обмін повідомленнями. Він вивчав, які мови, як правило, описані як не OO, не вистачає мов, які зазвичай називають OO, і він знайшов одне: обмін повідомленнями. Теоретик вежі зі слонової кістки приймає λ-обчислення і дивиться, який найменший набір особливостей полягає в тому, що треба було б додати, щоб отримати щось, що зазвичай називають ОО, і він доходить до відкритої рекурсії , яка в основному є будівельним блоком для обміну повідомленнями .
Йорг W Міттаг

3

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

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

Але моє реальне заперечення проти модульності полягає в тому, що воно не є ключовим для програм програмування або мов програмування ОО, наскільки архетипна мова програмування Smalltalk-80 взагалі не підтримує модулі. І коли ви задумаєтесь, мовна підтримка модулів у багатьох широко використовуваних OOPL є "слабкою".

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


Я ні вникаю в суперечки щодо інших 4 атрибутів, і про те, чи (наприклад), які моделі "спадкування" є чистими ОО. Крім того, хоча Алан Кей приписується тим, що він винайшов програмування OO, це не обов'язково означає, що його визначення OO / OOPL мають першість. Зрозуміло, що це не так. Він авторитетне джерело, але є й інші джерела , які дають інші визначення для ГО та OOPLs , що (на практиці) нести більшу вагу.


2
+1 Модульність насправді широко сприймається як бажаний атрибут більшості програмних систем, незалежно від мови програмування та використовуваної парадигми. Багато мов, які не є OO, підтримують модуляризацію.
Андрес Ф.

+1 @AndresF. коментар. Дійсно, "структуроване програмування" та "поетапне уточнення" (техніка для структури коду мислення) виходять з тижня "збільшення складності, що призводить до ще гіршого програмного забезпечення". Якби це передувало COBOL, ця мова не мала б такої негативної репутації IMHO. І я розглядаю OO прагматично як просто структуру вищого порядку. І я маю на увазі, що без вхідної основи структури OO не кращий, ніж найгірший COBOL.
radarbob
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.