У чому сенс ООП?


126

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

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

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

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


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

38
Незалежно від того, скільки разів запускається ця сама нитка, вона завжди викликає великий інтерес (незважаючи на те, що дублікати тут зазвичай не терпляться). І звичайно, обрана відповідь завжди така, яка погоджується з початковою думкою запитувача.
ТМ.

4
Проблема з OOP - це невдача поставити її в контекст. Він відмінний для деяких цілей, не для всіх цілей. Це чудовий інструмент. Це паршиве Євангеліє.
Майк Данлаве

16
Вибачте, але я не можу похитнути почуття, що ви ніколи не програмували мову, використовуючи якусь мову. Ось чому: OOP - це база операцій для бібліотек базових компонентів у всіх сучасних середовищах (Java, .NET, Python, Ruby - лише щоб назвати кілька основних-потокових). Всі ці базові бібліотеки використовуються щодня, тому, якщо це не рахується, я не знаю, що робить. Тож не помиляйтесь мене тут, але повторне використання коду, якщо факт - і надзвичайно поширений! Я не хочу, щоб це ні в якому разі не звучало образливо - просто вказую на це.
Маттіас Гринішак

2
@George Jempty: Це був Джоел Спольський у "Як Microsoft програв війну API" ( joelonsoftware.com/articles/APIWar.html ), заголовок уривку - "Автоматичні передачі виграй день".
GodsBoss

Відповіді:


24

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

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

Не достатньо просто прийняти методи OO та вимагати від розробників таких методів, оскільки це може негативно вплинути на продуктивність розробників, а також на якість розроблених систем.

Що з "Про зручність використання представництв ОО" з комунікацій ОСБ. Окт. 2000 р. У статтях в основному порівнюється ОО проти процесно-орієнтованого підходу. Існує багато досліджень про те, як люди, які працюють з методом ОО «думають» (Інт. J. Human-Computer Studies 2001, випуск 54, або Взаємодія людини та комп'ютера 1995, т. 10, має цілу тему щодо досліджень ОО), і з того, що я прочитав, нічого не вказує на певну природність підходу ОО, що робить його більш підходящим, ніж більш традиційний процедурний підхід.


18
Це чудово працює. Що не може зробити, це змусити поганих кодерів писати хороший код. Є періодичний відтінок і кричати проти цього з цієї причини.
хаос

6
@melaos: підсумок знаходиться посередині. OOP - це один із інструментальних інструментів, не єдиний, і він не може замінити навчання, досвід та судження.
Майк Данлаве

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

3
@melaos, підсумок (принаймні, цих статей) полягає в тому, що ніщо не говорить про те, що ОО є природним способом мислення для людей, і, таким чином, не є суттєвим перевагою будь-якого іншого способу побудови програм.
Svend

6
@Bill K: Це була одна з небагатьох відповідей, що дала цитати, а не махання руками та просто наполягання на тому, що ОО "повинно" бути кращим. Якщо література, що посилається, підтримує думку про те, що ОО не є якимось особливим поліпшенням чи певною користю, і, отже, підтримує мою первісну позицію, я не впевнений, чому я повинен нехтувати цим. Чи можете ви надати подібні довідки, які суперечать моїй ОП?
DrPizza

119

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

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

Існують набагато кращі, універсальніші моделі ( модель типу Haskell приходить на думку), але вони також часто складніші та / або важко ефективні. OOP - це гарний компроміс між крайнощами.


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

15
Я вважаю систему типу Haskell набагато більш інтуїтивно зрозумілою, ніж ОО.
axblount

4
@Konrad: "але це робить масштабні програми набагато простішими" - хммм, я не впевнений, що це правда. Це робить їх більш рентабельними в тому сенсі, що керування однією справою не повинно порушувати інше, а простіше? Отакий град ковтати ...
Мітч Пшеничний

2
@BradGilbert: звичайно, запитувач обрав відповідь, яка ідеально співпадає з думкою у своєму первинному запитанні. Звідки виникає питання, навіщо турбуватися задавати питання, якщо ви вже визначилися з своєю відповіддю?
ТМ.

2
@Mitch: Я б сказав, що ви не можете (на сьогоднішній день) писати масштабні програми без якоїсь орієнтації на об'єкт. Масштабний тут> 1М LOC.
Конрад Рудольф

45

OOP не в тому, щоб створювати повторно використовувані класи, а про створення класів, що використовуються.


7
Хороший! І так правда.
Toon Krijthe

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

42

Занадто часто клас використовується просто для синтаксичного цукру; він розміщує функції для типу запису у власному маленькому просторі імен.

Так, я вважаю це занадто поширеним. Це не об'єктно-орієнтоване програмування. Це об'єктне програмування та орієнтоване на дані програмування. За свої 10 років роботи з OO Languages ​​я бачу людей, які в основному виконують об'єктно-орієнтоване програмування. OBP виходить з ладу IMHO дуже швидко, оскільки ви отримуєте найгірше з обох слів: 1) Процедурне програмування без дотримання перевіреної структурованої методології програмування та 2) OOP, не дотримуючись перевіреної методології OOP.

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

Більшість розробників, які працюють на мовах OOP, використовують приклади OOP, зроблені правильно, у рамках та типи, якими вони користуються щодня, але вони просто не знають про це. Ось кілька дуже простих прикладів: ADO.NET, Hibernate / NHibernate, Framework Logging Framework, різні типи колекціонування мов, стек ASP.NET, стек JSP і т. Д. Це все, що сильно покладається на OOP у своїх кодових базах.


32

Повторне використання не повинно бути метою OOP - або будь-якої іншої парадигми з цього приводу.

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

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

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


3
правда щодо повторного використання та ОО є окремими проблемами.
Дан Розенстарк

28

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

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

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


2
Я щойно дав вам нагороду, яка закинула вас вище 2000 балів - сподіваюся, вона дотримається. : P
Джейсон Бантінг

5
Рідко можна побачити, як ООП ефективно навчається.
Джон W

Ваша відповідь дуже схожа на ту, яку дають тренери Agile / Scrum, коли її запитують, чи є сенс - "це дуже корисно, якщо ви це зробите правильно; якщо ви не вдається, то ви повинні робити це неправильно". Складати такі слова, як "багаторазове використання" та "ремонтопридатне", легко, але оцінити ці якості в фактичному коді непросто, а також не існує рецепту, який говорить про те, як писати хороший OOP (незважаючи на тисячі книг, які намагаються це зробити) . Ми також отримуємо шкідливу звичку нібито ігнорувати обладнання, що призводить до жахливої ​​продуктивності на вівтарі, щоб уникнути передчасної оптимізації.
Том

21

Я думаю, що використання непрозорих контекстних об'єктів (HANDLEs в Win32, FILE * s в C, щоб назвати два відомі приклади - пекло, HANDLE живуть з іншого боку бар'єру в режимі ядра, і воно дійсно не отримує значно більше інкапсульованого, ніж це) міститься і в процесуальному кодексі; Я намагаюся бачити, як це щось особливе для ООП.

HANDLEs (та решта WinAPI) - це OOP! C не підтримує OOP дуже добре, тому немає спеціального синтаксису, але це не означає, що він не використовує однакові поняття. WinAPI - це будь-який сенс цього слова, об'єктно-орієнтований фреймворк.

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


1
Я ось-ось збирався розмістити щось дуже схоже.
Бред Гілберт

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

14

Його парадигма програмування. Розроблена для того, щоб полегшити нам простим смертним розбити проблему на більш дрібні, працездатні частини.

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

Я з іншого боку вважаю це корисним, тому буду :)


14

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

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

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


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

"Поняття про клас, який відокремлює інтерфейс від реалізації" --- Я думав, що інтерфейси - це інтерфейси, а класи - це реалізація? Можливо, я просто надто орієнтований на процес мислитель, але я вважаю, що це поліморфізм, дисперсія коду з однорідністю у використанні, це і є рушником ООП; Я вважаю, що "купа C функцій" відокремлює інтерфейс від реалізації так само добре, як і "клас java". Може, я все помиляюся?
Йонас Келькер,

2
@Jonas - Вашій "купі функцій C" --- я погоджуюся, що вони можуть відокремити інтерфейс від реалізації, і в цей момент він починає бути OOP. Якщо приклад продовжує визначати структуру С, на якій працює API, ви в основному створили інкапсуляцію (особливо, якщо API працює непрозоро на структурі) ... і тоді це справді OOP в C.
Tall Jeff

12

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

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

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

Зараз вони схожі на лемінгу після перепродаж інших хороших ідей, таких як функціональне програмування.

То що б я робив інакше? Багато, і я написав про це книгу. (Це не надруковано - я не отримую цента, але ви все одно можете отримати копії.) Amazon

Моя конструктивна відповідь - дивитися на програмування не як на спосіб моделювання речей у реальному світі, а як на спосіб кодування вимог.

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

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

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


Класно. Оскільки книга не надрукована, ви не хочете надавати PDF-файли, чи не так? Amazon відправляє НЕБЕЗПЕЧНО в Аргентину ...
Dan Rosenstark

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

@Daniel: хороша пропозиція. Я попрацюю над цим і побачу, чи зможу я приєднати його до свого блогу. Ви знайдете це трохи старомодно, бо це було у 94 році, але принципи не змінилися.
Майк Данлаве

1
@Mike Dunlavey Шановний пане, чи можу я підтримати цікавість @ yar, щоб дізнатися, чи є можливість прочитати / отримати вашу книгу [хоча б частково] через Інтернет? Як здається, запропонований / розроблений вами спосіб ефективного програмного забезпечення [компонента] / розробки відповідає тій, що [я нещодавно визнав] я хотів би навчитися або навчити (на відміну від, ну, "вантажного" способу, який добре вводиться написані, але болісно неоднозначні основні книги ОО). Заздалегідь дякую [і привіт від Росії :)].
mlvljr

1
@mlvljr: Гаразд. Найшвидшим способом може бути просто сканувати його та зробити великий pdf-файл. Я побачу, чи зможу я дістатися до нього в найближчі кілька днів. Не дозволяйте мені забути [щирі співчуття за останні події в Москві та привітання від мокрого Массачусетса].
Майк Данлаве

11

РУЧКИ (та решта WinAPI) - це OOP!

Вони, хоча? Вони не успадковуються, вони, звичайно, не замінюються, їм не вистачає чітко визначених класів ... Я думаю, що вони далеко не "OOP".

Ви коли-небудь створювали вікно за допомогою WinAPI? Тоді вам слід знати, що ви визначаєте клас ( RegisterClass), створюєте його екземпляр ( CreateWindow), викликаєте віртуальні методи ( WndProc) та методи базового класу ( DefWindowProc) тощо. WinAPI навіть бере номенклатуру від SmallTalk OOP, називаючи методи «повідомленнями» (Window Messages).

Ручки можуть бути не успадкованими, але тоді, finalу Java є. У них не бракує класу, вони є заповнювачем класу: саме це означає слово "обрати". Якщо дивитися на такі архітектури, як MFC або .NET WinForms, відразу очевидно, що, крім синтаксису, нічим не відрізняється від WinAPI.


WINAPI не є OOP. Він просто показує спосіб написання розширюваного процесуального кодексу. Хороші методи хороші, незалежно від того, є вони OOP чи ні. Я можу писати програми WINAPI на C і використовувати ті самі методи у власному коді, тож я думаю, що C - це OOP.
bruceatk

3
Це може бути не те, що мав на увазі Алан Кей (google it!), Але все-таки це OOP.
Конрад Рудольф

11

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


4
Ти не чув? SOA - минуле. Сьогодні саме хмарні обчислення стануть нашими рятівниками.
DrPizza

Мені дуже цікаво, чи відповіді іронічні чи ні. Мені подобається іронія, але, як правило, її проголошення вниз, це змушує мене замислитися ...
Лена Шіммель

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

Питання досить риторичне, тому це правильна відповідь (і найкраща відповідь).
Джефф Девіс

10

OOP добре піддається програмуванню внутрішніх комп'ютерних структур, таких як "віджети" графічного інтерфейсу, де, наприклад, SelectList і TextBox можуть бути підтипами Item, який має загальні методи, такі як "переміщення" та "зміна розміру".

Біда в тому, що 90% з нас працюють у світі бізнесу, де ми працюємо з такими бізнес-концепціями, як фактура, працівник, робота, замовлення. Вони не піддаються OOP так добре, оскільки "об'єкти" є більш туманними, можуть змінюватися відповідно до реінжинірингу бізнесу тощо.

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


Це все правда, але ... можливо, той факт, що OOP може спростити ДЕЯКІ, не пов'язані з бізнесом аспекти програми (наприклад, реалізація інтерфейсу користувача), саме одна з головних причин, чому розробник (нарешті!) Може витратити більше часу на роботу над бізнесом -споріднені аспекти?
Ярик

10

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

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

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

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


1
Я ніколи не досягав чистої фази радості процедурно чи OOP під час читання коду. :)
bruceatk

1
Чималої радості, ні, але, можливо, трохи посмішки?
Дан Розенстарк

9

Можливо, капелюшок, коліна чи дерево - це не стілець, але всі вони ISITtable.


2
Вам ніколи не доводилося користуватися мовою ОО без інтерфейсів? Вам пощастить.
finnw

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

8

Я думаю, що речі реального світу - це об'єкти

Ти робиш?

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

Так само й інші речі, які ви згадуєте.

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


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

1
Я погоджуюся, що такі методи, як Send () або Pay (), є "неприродними" для рахунків-фактур. Але, наприклад, як щодо загальної суми як отриманого, але НЕЧАСНОГО атрибута рахунка-фактури? Хіба це не приклад того, що OOP дозволяє моделювати дуже "природним" способом навіть для абсолютно інертних суб'єктів реального життя? Сам по собі не величезне досягнення, але все ж ...
Ярик

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

7

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

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


7

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

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

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

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

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


Мені подобається ваш останній абзац найкраще.
Майк Данлаве

6

@Sean

Однак, розбиваючи загальну функціональність на базовий клас, потім повторно використовуючи, що в інших класах нащадків - це дуже елегантна річ, ІМХО!

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


6

@Konrad

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

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


6

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

Це не обов'язково має значення, що рахунок-фактура насправді не є "об'єктом" з функціями, які він може виконувати сам - екземпляр об'єкта може існувати просто для виконання функцій над даними, не знаючи, який тип даних насправді є. Функцію "invoice.toJson ()" можна успішно викликати, не знаючи, що таке дані "рахунок-фактура" - результат буде Json, незалежно від того, якщо він походить з бази даних, XML, CSV або навіть іншого об'єкта JSON . З процедурними функціями ви раптом повинні знати більше про свої дані, і в кінцевому підсумку виконайте такі функції, як "xmlToJson ()", "csvToJson ()", "dbToJson ()" і т.д. ВЕЛИЧЕЗНА головний біль, якщо ви коли-небудь змінюєте базовий тип даних.

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

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


5

@CodingTheWheel

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

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

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


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

5

@Jeff

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

Яка має більш приховану реалізацію: іострими C ++, або C FILE * s?

Я думаю, що використання непрозорих контекстних об'єктів (HANDLEs в Win32, FILE * s в C, щоб назвати два відомі приклади - пекло, HANDLE живуть з іншого боку бар'єру в режимі ядра, і воно дійсно не отримує значно більше інкапсульованого, ніж це) міститься і в процесуальному кодексі; Я намагаюся бачити, як це щось особливе для ООП.

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


5

У єдиному блозі розробників, який я прочитав, тим хлопцем Joel-On-Software-засновником-SO, я давно прочитав, що ОО не призводить до підвищення продуктивності. Автоматичне управління пам’яттю робить. Класно. Хто може спростувати дані?

Я все ще вважаю, що OO - це не-OO, що програмування з функціями - це програмування всього вбудованого.

(І я повинен знати, як я почав з GWBasic.) Коли ви рефакторний код використовуєте функції, variable2654стає variable3методом, який ви використовуєте. Або ще краще, це ім'я, яке ви можете зрозуміти, і якщо функція коротка , це називається, value і цього достатньо для повного розуміння.

Коли код без функцій стає кодом з методами, ви можете видалити милі коду.

Коли ви реорганізовувати код , щоб бути дійсно OO, b, c, q, і Zстати this, this, thisі this. А оскільки я не вірю у використання thisключового слова, ви можете видалити милі коду. Насправді ви це можете зробити, навіть якщо використовуєте this.



Я не думаю, що ОО є природною метафорою.

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

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



Деякі основні поняття - це справді класні інструменти

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



У чому сенс ООП?

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

Більшість розробників OOP призначено неправильно зрозуміти

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



Щодо вашого міні-есе / питання

Я хотів зазначити, що ти маєш рацію. Повторне використання - це мрія здебільшого. Ось цитата Андерса Хейльсберга на цю тему (блискуча) звідси :

Якщо ви попросите початківців програмістів написати календарний контроль, вони часто думають собі: "О, я буду писати найкращий у світі контроль календаря! Це буде поліморфно щодо типу календаря. У ньому будуть дисплеї, і глушники, і це, те, і інше ». Їм потрібно відправити календарну заявку за два місяці. Вони ставлять всю цю інфраструктуру на місце контролю, а потім витрачають два дні на написання шаленої програми календаря поверх неї. Вони подумають: "У наступній версії програми я збираюся зробити набагато більше".

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


4

Ви коли-небудь створювали вікно за допомогою WinAPI?

Більше разів, ніж мені хочеться згадати.

Тоді вам слід знати, що ви визначаєте клас (RegisterClass), створюєте його екземпляр (CreateWindow), викликаєте віртуальні методи (WndProc) та методи базового класу (DefWindowProc) тощо. WinAPI навіть бере номенклатуру від SmallTalk OOP, називаючи методи «повідомленнями» (Window Messages).

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

Ручки можуть бути не успадкованими, але тоді, у Java є остаточний. У них не бракує класу, вони є заповнювачем класу: саме це означає слово "обрати". Якщо дивитися на такі архітектури, як MFC або .NET WinForms, відразу очевидно, що, крім синтаксису, нічим не відрізняється від WinAPI.

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

Це насправді це? Найкращі біти OOP - це просто ... традиційний процесуальний кодекс? Це велика справа?


Ви повинні пам’ятати, що інтерфейс Win32 в основному був реалізацією Win16. Який був розроблений понад два десятиліття тому.
Бред Гілберт

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

4

Я повністю згоден з відповіддю InSciTek Jeff , я просто додам наступні уточнення:

  • Приховування та інкапсуляція інформації: критично важливий для будь-якого коду, який можна отримати. Це можна зробити, будьте обережні на будь-якій мові програмування, не вимагаючи функцій OO, але це зробить ваш код трохи OO-подібним.
  • Спадщина: Є одна важлива область застосунку, для якої всі ці OO є своєрідними і містять- відносини - ідеально підходять: Графічні інтерфейси користувача. Якщо ви спробуєте створити графічні інтерфейси без підтримки мови OO, у будь-якому випадку ви створите функції, подібні до ОО, все одно, і без мовної підтримки складніше і більш схильні помилки. Поляна (нещодавно) і X11 Xt (історично), наприклад.

Використання функцій ОО (особливо глибоко вкладених абстрактних ієрархій), коли немає сенсу, безглуздо. Але для деяких областей додатків дійсно є сенс.


Так, я думаю, ви повинні використовувати OOP для об'єктів, функціональне програмування для функцій ...
Svante

4

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

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

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

Крім того, приєднання функцій до цих сторінок набагато чистіше. Я можу зробити proCurrentPage-> CleanCache (); Далі йде proDisplayItem-> RenderPromo (); Якби я лише зателефонував до цих функцій і припустив, що наявні дані є, хто знає, яке зло відбудеться. Крім того, якщо мені довелося передати правильні змінні в ці функції, я знову повернувся до проблеми наявності різноманітних змінних для різних продуктів.

Натомість, використовуючи об’єкти, всі мої дані про продукти та функції є приємними, чистими та зрозумілими.

Однак. Велика проблема з OOP - це коли хтось вважає, що ВСЕ має бути OOP. Це створює масу проблем. У мене в базі даних 88 таблиць. У мене всього близько 6 класів, і, можливо, у мене повинно бути близько 10. Мені точно не потрібно 88 занять. Більшість випадків прямого доступу до цих таблиць цілком зрозуміло в тих обставинах, якими я їх використовую, і OOP насправді ускладнить / нудний отримати основний функціонал того, що відбувається.

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


3

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

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


2

"Реальний світ не є" OO ","

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

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


2

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

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

Вбудований у мову OO просто дає програмісту ще один виразний засіб.

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

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