Чому OOP важкий? [зачинено]


91

Коли я почав використовувати об’єктно-орієнтовану мову (Java), я майже просто перейшов у "Cool" і почав кодувати. Я ніколи не думав про це до недавнього часу, прочитавши багато питань про ООП. Загальне враження, яке я створюю, таке, що люди борються з цим. Оскільки я не вважав це важким і не сказав би, що я геній, я думаю, що, мабуть, щось пропустив або неправильно зрозумів.

Чому OOP важко зрозуміти? Це важко зрозуміти?


72
Я протидію: це не важко зрозуміти, просто важко освоїти. Програмування в цілому відбувається таким чином.
Стівен Еверс

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

5
@ acidzombie42: функціонал зовсім не дивний. вам не доведеться писати список команд для зміни вмісту змінних, що представляють розташування в ОЗП. змінні представляють значення, ви не змінюєте значення; 42 залишається 42, х залишається х - що б не було. ви записуєте функції, які відображають від їх параметрів до результатів. Значення: числа, списки значень, функції від значень до значень, програми, що створюють побічні ефекти та отримане значення при виконанні тощо. таким чином, результат основної функції буде обчислений компілятором, тобто програмою, яку можна виконати.
comonad

5
Я нещодавно вчився Haskell Чим більше я дізнаюся і розумію про функціональне програмування, тим більше мені здається, що OOP важко. Я думаю, що основною причиною цього є OOP намагається зв'язати разом дані (об’єкт / клас) разом із функцією, яка діє на них (метод). Це джерело проблеми, і багато моделей дизайну OOP розроблені, щоб уникнути зв’язування даних та функцій разом. Наприклад, заводський зразок використовується для відділення конструктора (який є функцією) від фактичного об'єкта, над яким він працює.
ming_codes

1
Тому що це неправильно названо. Це дійсно має бути предметно-орієнтоване програмування, оскільки Суб'єкт виконує Дію (дієслово), а Об'єкт отримує Дію - Джон кинув м'яч. Тож johnsBall.throw () насправді не має сенсу.
Кріс Кадмор

Відповіді:


119

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

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

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

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


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

3
Особливо мені подобається ваш 1-й і 3-й бали. Мій друг гагає по дизайнерських моделей, і я постійно кажу йому, що якщо ви просто використовуєте хороший OOP, більшість з них виходить дуже природно з початкової проблеми.
CodexArcanum

7
+1 для "Важкою частиною для мене було" чому "це". Щоб зрозуміти та застосувати основи мови (інкапсуляція), принципи проектування та методи рефакторингу, потрібно певний час та зусилля до загальних рішень (моделей дизайну).
Белун

12
Я погоджуюся з №1, із застереженням, що вам потрібно зробити кращу роботу, пояснюючи ОО людям, які вже вміють програмувати процедурно, ніж це було зроблено, коли я вчився. Ні, не корисно чи інформативно говорити про Catклас, який успадковує Mammal, використовувати реальний приклад із реальної програми, яку ми б написали процедурно. Як і проста структура даних.
Carson63000

4
-1 Шаблони дизайну сьогодні настільки сильно наголошені. Вони важливі, безумовно, але: по-перше, вони важливі для всіх парадигм: функціональних, структурованих, а також ОО; по-друге, вони не є частиною парадигми, а лише зручним доповненням, яке ви можете використовувати, як і багато інших. @SoftwareRockstar це добре пояснює у своїй / її відповіді.
CesarGon

56

Я думаю, що є кілька факторів, про які ще не було сказано.

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

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

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

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

  1. Не запевняйте нічого про те, скільки коліс має автомобіль - але це, як правило, призводить до неявного припущення, що воно завжди буде 4, і код, який, ймовірно, може зламатися на інше число.
  2. Зауважте, що всі автомобілі мають чотири колеса, і просто класифікуйте ці інші як "не машини", хоча ми знаємо, що вони є насправді.
  3. Запроектуйте клас так, щоб він міг змінювати кількість коліс, на всякий випадок, навіть якщо є хороший шанс, що ця можливість ніколи не буде потрібна, використана або перевірена належним чином.

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

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

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

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


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

7
Хе, я просто думав про це днями. Те, як весь перший навчальний матеріал, який я прочитав на ООП, здавалося, зосереджений на спадкуванні, в той час як мій досвід все більше і більше говорить про те, що успадкування здебільшого марно, якщо не шкідливо.
rmac

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

1
@OnesimusUnbound: різниця полягає в тому, що загальне програмування - це реальний, практичний спосіб зробити щось зроблене, тоді як програмування, орієнтоване на таблицю, - це здебільшого лунатик, який стосується теорії про те, як щось могло працювати (читайте через старі повідомлення TopMind в comp.object, і ви Я побачу, що я маю на увазі - насправді повідомлення можуть не бути старими; адже я знаю, він продовжується навіть сьогодні).
Джеррі Труну

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

26

ООП вимагає вміння абстрактно мислити; подарунок / прокляття, яких насправді мало хто, навіть професійні програмісти.


35
Всі програми є абстрактними.
JeffO

28
@Jeff O - Я не згоден. Програмування вимагає лише вміння розповісти комусь, як щось робити поетапно. Якщо ви можете сказати комусь, як зробити бутерброд з арахісового масла і желе, у вас є можливість вводити команди в інтерфейс програмування. Це зовсім інший набір навичок, ніж абстрактно моделювати сендвіч ap, b & j та те, як він взаємодіє зі світом.
Джон Крафт

16
Подавати комусь 2 олівці, а потім вручити їм 1 олівець і запитати, скільки у них олівців, це конкретно. 2 + 1 = 3 абстрактно.
JeffO

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

2
@KonradRudolph Чудова точка. +1 для "Все інше буде занадто складним без абстракцій" .
Картик Сріенівасан

21

Я думаю, ви можете підсумувати основні труднощі таким чином:

// The way most people think.
Operation - object - parameters
// Example:
Turn the car left.

// The way OOP works conceptually
Object - operation - parameters
// Example:
Car.Turn(270);

Звичайно, люди можуть звикнути до карти "лівих", як 270, і так, кажучи "Car.Turn" замість "повернути машину" - це не такий величезний стрибок. АЛЕ, щоб добре впоратися з цими об’єктами та створити їх, ви повинні перевернути те, як ви зазвичай думаєте.

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


7
Гарне розуміння. Я думаю, що проблема полягає в тому, що в реальному житті не так багато може зробити "об'єкт", що не стосується інших об'єктів. OO працює добре, тому що об'єкти говорять про зміну свого внутрішнього стану: rectangle.enlarge (margin_in_pixels), але я зрозумів межі років тому. Одного разу ми програмісти встановлювали обладнання. Хтось пограбував "викруткою" смішно, але це задумалося: звичайно, гвинт може змінити його орієнтацію, але це дійсно операція між шафою і гвинтом; жоден об'єкт не може виконати завдання самостійно. OO просто недостатньо хороший.
DarenW

3
+1, після років написання "substr (дата, 0,4)", важко написати "date.substring (0,4)"
ern0

4
+1 для фрагмента коду. На ньому чітко зображений власне процес мислення.
Картик Сріенівасан

2
Я насправді прочитав би це як команду, яку ви надсилаєте. Як і в "скажіть машині повернути ліворуч". Oop базувався на надсиланні повідомлень до об’єктів, тож я б так трактував це.
bunglestink

1
Добре розуміння, тому, можливо, OOP більше підходить для моделювання "системних агентів"?
Qbik

21

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

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

  • важливі поняття ховаються за незвичайними іменами (FP: Що таке монада? OOP: Чому вони іноді називають їх функціями та методами?)

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

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

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

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


8
Я особливо ненавиджу метафоризм, частіше за все вони плутають, а не описують.
Лі Лі Раян

3
"Тоді я пізніше стрибнув, як зрозумів, що виклик методу з об'єкта дуже схожий на здійснення статичного виклику з цим об'єктом як першого параметра." Я б хотів, щоб це було підкреслено більше від початку, як це є мовами, як Python.
Jared Updike

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

Чудова відповідь! +1 для пояснення того, що перший крок до розуміння ООП буде більш значущим, ніж те, що з’явиться пізніше, як природні розширення з хорошим розумінням фундаменту. : D
Картик Сренівасан

дитто про "стрибкове" навчання: Коли я почав сприймати ООП як "просто" модульну / структуровану / ступінчасту побудову, але на стероїдах; коли я переписав декілька дуже старих і непростий програм COBOL. Глобальна сфера COBOL, незважаючи на те, що я по суті застосував принципи ОО з користувацькими структурами записів, одноцільовими змінними та чітко зосередженими, модульними та структурованими абзацами (методами).
radarbob

15

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

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


13

Я не згоден з відповіддю dsimcha здебільшого:

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

  2. Індивідуальні методи в хороших програмах OO НЕ мають тенденції бути процедурними. Це стає все більш істинним із розвитком мов OO (читайте C #, тому що крім C ++, це єдина інша мова OO, яку я знаю) та їх синтаксис, який стає складнішим з кожним днем ​​(лямбда, LINQ до об'єктів тощо). Єдина схожість між методами ОО та процедурами в процедурних мовах - це лінійний характер кожного, який, я сумніваюся, зміниться незабаром.

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

  4. Я не думаю, що моделей дизайну взагалі слід навчати програмуванню ОО, оскільки вони взагалі не є основоположними для програмування ОО. Безумовно, можна бути хорошим програмістом OO, не знаючи нічого про шаблони дизайну. Насправді людина навіть може користуватися відомими моделями дизайну, навіть не знаючи, що вони зафіксовані як такі з власними іменами і що про них написано книги. Що слід викладати принципово, це такі принципи дизайну, як "Одинична відповідальність", "Відкрити закриття" та "Сегрегація інтерфейсу". На жаль, багато людей, які вважають себе програмістами OO в наші дні, або не знайомі з цією фундаментальною концепцією, або просто вирішують її ігнорувати, і саме тому у нас так багато сміттєвого коду OO.

Щоб відповісти на питання оригінального плаката, так, OO - це важче зрозуміти, ніж процедурне програмування. Це тому, що ми не мислимо з точки зору властивостей та методів об’єктів реального життя. Наприклад, людський мозок не охоче мислить "TurnOn" як метод телебачення, але сприймає це як функцію включення людини на телевізор. Так само поліморфізм - це іноземне поняття для людського мозку, який, як правило, бачить кожен об'єкт реального життя лише одним «обличчям». Спадщина знову не є природним для нашого мозку. Тільки тому, що я розробник, це не означає, що мій син був би таким. Взагалі кажучи, людський мозок повинен бути навчений вивчати ОО, тоді як процедурні мови є більш природними для цього.


2
+1 - Я теж не думаю, що шаблони дизайну не потрібні для викладання навчальних програм на фундаментальному рівні, ти можеш бути хорошим програмістом OOP і не знаєш жодної моделі дизайну. З іншого боку, ти, як правило, бачиш, що відомі дизайнерські зразки виходять, природно, від хороших програмістів OOP. Шаблони дизайну завжди виявляються, не вигадуються.
Gary Willoughby

1
+1 - чудова відповідь. Мені подобається четвертий пункт, який ви заявили. Це дуже правда, що можна бути хорошим програмістом OO, не знаючи, що насправді дизайнерські малюнки!
Картик Сріенівасан

Я погоджуюся з №4, тому що більшість моделей дизайну - це не що інше, як підхід «балончик / клейка стрічка» для виразного кодування навколо обмежень мови. В інших парадигмах моделі дизайну можуть бути абсолютно різними і засновані на власних обмеженнях. Я не погоджуюся з 2, LINQ та лямбдахами все ще виконуються процедурно, вони просто надають акуратно упаковані абстракції вищого рівня. Витратьте деякий значний час на розробку з динамічно набраною процедурною / функціональною мовою, як JavaScript, і ви побачите, що я маю на увазі.
Еван Плейс

6

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


5

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


5

Об'єктно-орієнтоване програмування саме по собі не є складним.

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

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


"Мій особистий досвід полягає в тому, що для цього потрібна велика практика у всіх ситуаціях, коли ви хотіли б, щоб ви робили це по-іншому, щоб цього разу зробити це досить добре". OOP здається кодифікованим переліком способів не зробити це неправильно, що не має сенсу, поки ви не зробили це неправильно усіма цими способами.
Jared Updike

@Jred, не зовсім. Порівняйте це з розв’язуванням содука. Існують різні хитрощі, які ви можете вирішити, але потрібен час і практика, щоб зробити це добре, не зволікаючи з ними.

Якщо хтось думає про «загальний базовий об’єкт», як про загального предка, то це стає зрозумілим. Це дійсно так просто. Важко зрозуміти, чи не є так багато оманливих пояснень з боку людей, які намагаються виглядати розумними.
annoying_squid

4

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

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

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

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


+1 Я почуваюсь так само, але дуже багато натискань у зворотному напрямку, включаючи Рубін міксин ... що дає зрозуміти, що суворий ОО не для всіх.
Dan Rosenstark

@ Yar Yep, це майже все, що я говорив. Хоча я особисто не можу уявити собі нічого кращого (і Рубі загнав мене в NUTS за рік, коли я ним користувався), я починаю визнавати, що всі мають різний спосіб бачити це. Можливо, деякі люди використовують дотик чи слух, коли думають замість того, щоб візуалізувати, і ОО просто не кидає на них.
Білл К

Я думаю, що це також допомагає заохочувати більш природні угоди про іменування. Вам більше не потрібно кодувати тип функції у назві функції (як INSTR) - тому що ім’я додається до типу (як string::find)
Кен Блум

@Ken хоча я згоден, я думаю, що це більше питання сильного набору тексту, ніж OO - у Ruby є OO, але ти втрачаєш багато інформації про тип через типу качки - Ruby прагне просто сказати "send (it)" та очікуй ви знаєте, який магічний метод "він" має реалізувати, щоб працювати.
Білл К

@Bill, ти маєш рацію. Це більше питання мов, які підтримують загальне програмування. Ви можете отримати приємні умови природного іменування за допомогою модулів і типів класових систем, таких як Haskell, і нічого не існує про Haskell. Якби у C було перевантажено, ви могли б отримати однакові родові назви у C.
Кен Блум

4

Я дуже зробив програмування GW-Basic та Turbo Pascal перед тим, як вводитись в OO, тож спочатку це DID зробив голову.

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

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


Цікава точка зору. Поки я намагаюся зрозуміти масштабні проекти C ++, я думаю, що я протилежний, мислю в першу чергу з точки зору даних, "сигнальний шлях" бітів від якогось "входу" до якогось "виходу". Хоча я теж робив багато базових і Паскаль, моє найдавніше технічне мислення було в галузі електроніки.
DarenW

3

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

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

Крім того, є багато поганого OOP там, якщо люди читають / бачать, що тоді легко зрозуміти, чому їм може бути важко.

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


5
Якщо ви приїжджаєте з навчальних закладів, типи іграшкових програм, які ви там пишете, справді здаються безглуздими і в ООП. Я почав вивчати C в коледжі, і це було досить легко зрозуміти, оскільки кожна програма була на 1 сторінці, менше 100 рядків. Потім ви намагаєтесь навчитись OOP, і для цього потрібно весь цей багаж та накладні предмети, і це здається безглуздим. Але поки ви не написали програму для багатьох файлів і кількох тисяч рядків, важко зрозуміти, чому будь-який стиль програмування корисний.
CodexArcanum

3

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

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

OOP - це абстрагований спосіб представлення абстракцій.

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


2

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

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


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

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

2

Мотивація. Важче щось навчитися, коли ти не бачиш, чому, а також коли не можеш дивитись на те, що ти робив, і розуміти, чи зробив ти це правильно чи ні.

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


Люди завжди розмовляють про Singleton, але тоді його завжди запрошують на вечірку. Але це правда, він не є OO OO DP.
Дан Розенстарк

-1

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

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


1
OO примха? Скільки років вашим студентам - я підозрюю, що ця "принадність" старша за них (спочатку я зробив - що я знав, що це я - був Симула приблизно в 1983/4, а Симула не була новою на той момент)
Мерф

@Murph Це було приблизно в 2004-2005 роках, і студентам було напевно понад 45-50 (професійні програмісти в Іберії).
Дан Розенстарк

Гаразд, я можу побачити, як вони, можливо, пропустили початок справи OO. Але до 2004/5 року ми добре ввійшли в .NET, який є в значній мірі OO стіною до стіни (-: Є такі речі в розвитку, які можна було б описати як примхи, але ті, які не переймаються швидко, як правило, перетворюються на хороші речі
Мерф

1
@Murph, чесно кажучи, ці хлопці були програмістами мейнфреймів, яких вони намагалися перетворити на Java. Це був насправді кумедний та унікальний досвід (не звичайний тариф на дні мого тренера Java). Це є правдою, однак, що вони бачили багато речей , які приходять і йдуть, але , очевидно , OO більше , ніж захоплення. Окремо зауваживши: я сподівався на те, що ця тестова одиниця тестує як примха, але тепер я вважаю, що в мене є багато тестів для одиниць ... :)
Dan Rosenstark

-1

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

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

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

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


-1

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

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

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

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

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


1
Пару точок або об’єктів слід розглядати як об’єкт. І відстань слід сприймати як функцію від об’єкта. Використання об'єктів не означає, що ви робите об'єкт з усього.
Gangnus

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

Це залежить від мови - у SmallTalk відстань (і все) є об’єктом. Але в C # ви вже згадали, що це було б погано.
Gangnus

-2

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

Погодилися, що моделі дизайну повинні дотримуватися принаймні паралельно OOP.


-2

Основним стрибком для мене було саме розуміння абстрактної концепції ООП. Зараз я дуже новачок у програмуванні, взагалі програмував рік-півтора, тому моє введення в ООП було з Actioncript та Processing. Коли я вперше дізнався кодування Actioncript, його не було в OOP. Я навчився кодувати безпосередньо на панелі "Дії", і саме тому я засвоїв основні основи програмування (змінні, функції, цикли тощо). Тож я навчився цього робити щось безпосередньо на сцені у Flash або Processing.

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


вау частина цього didnt не мала ніякого сенсу. "Все було дуже абстрактно і важко обробляти між класами та екземплярами об'єктів і т. Д. Але мови програмування стало набагато простіше зрозуміти, як тільки я отримав OOP. Але начебто був потрібен стрибок faitl, щоб зробити ці з'єднання спочатку"

-2

Рецепт

Гарне розуміння OOP = Хороший наставник чи хороші книги чи обидві + особистий інтерес + практика.

Особистий інтерес

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

Практика, практика та практика

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

Як висловлюється: "Немає заміни на важку працю і не існує швидкого доступу до успіху".

Удачі!

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