Чи є об'єктно-орієнтоване програмування рішенням складності? [зачинено]


18

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


15
Трудне завдання есе? ; p
гленатрон

1
Питання не має сенсу, оскільки складності немає. Існують стратегії поводження зі складністю (зокрема, внутрішньою, непридатною складністю). Але рішень, ні там немає. Це як шукати рішення зведення однієї відстані фізичної милі до нуля.
luis.espinal

1
Об'єктно-орієнтоване програмування - це інструмент управління складністю.
Роберт Харві

Питання: Чи можете ви запрограмувати складні проблеми з OOP? - Відповідь: Звичайно. Якщо ви використовуєте OOP, це буде складним.
mouviciel

"Це може бути суперечливим" робить його предметом обговорення, а не технічним питанням ...
jwenting

Відповіді:


24

Немає рішення складності.

У «Міфічному людині-місяці» Фред Брукс обговорює різницю між випадковою та суттєвою складністю в програмуванні. Випадкова складність зумовлена ​​нашими інструментами та методами, такими як необхідність писати та перевіряти додатковий код мовою, оскільки ми не можемо висловити свої ідеї безпосередньо тощо. Нові методи та прийоми дозволяють зменшити випадкові складності. Я можу писати програми швидше та краще, ніж міг двадцять п’ять років тому, бо маю кращі мови та інструменти.

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

Тому він стверджував, що срібної кулі не буде, що писати програмне забезпечення буде і надалі важко.

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

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


3
Видання 20-ї річниці також містить "" No Silver Bullet "Refired", в якому він називає OOP "латунною кулею", і каже, що це "... дуже перспективна концепція".
Джеррі Труну

18

Я очікую, що незабаром ви отримаєте кілька кращих відповідей, але ось простий:

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

* Тому що ніщо не може «вирішити» складність


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

8
@Robert: Я не заперечую, що ви насправді моделюєте об'єкти реального світу в OOP дуже часто - просто простіше думати більшість програмувань з точки зору об’єкта (навіть якщо це об'єкти socket-proxy та модель-фасад), тому що саме так ми бачимо світ собак та качок у реальному житті.
Fishtoaster

2
Ні, це поширена помилка щодо ООП. Ви не повинні моделювати свою програму на основі об'єктів реального життя. У реальному житті такого поняття, як BufferReader.
hasen

1
@Hasen j: Так, це я сказав, коли уточнив у своєму коментарі.
Fishtoaster

Є дуже хороша дискусія на programmers.stackexchange.com/questions/16189/…
Білл Мішелл

15

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

Якщо ви повернетесь до її коренів, я вважаю, що на Алана Кей дуже сильно вплинув "ліс".

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

Якщо ви подивитесь на кінець "Лекції 3а: Приклад Хендерсона Ешера" SICP , Хал Абелсон пропонує, щоб складність управлялася не шляхом розбиття завдання на більш дрібні підзадачі, а шляхом створення шарів абстракції. На найвищому рівні ви висловлюєте рішення складної проблеми з точки зору рішення на нижчий рівень абстракції.

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

На жаль, в наш час OOP використовується (ab) для написання коду / структур спагетті.

Я приведу приклад: FPS-гра для багатьох гравців.

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

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

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

І так далі, і так далі.

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

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

Ось фрагмент, який я цитував з лекції: http://www.youtube.com/watch?v=CYtrfncMqHQ


5
Як і багато інструментів, OOP є високоефективним, коли він використовується розумно і продумано, і не настільки ефективний при зловживанні.
Роберт Харві

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

1
Я вважаю, що теоретична концепція, яка не «зіпсована прийняттям мейнстриму», дозволить краще керувати складністю в реальних проектах ... химерною.
Майкл Боргвардт

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

@hasen j: OTOH, відповідно більше ймовірність того, що "оригінальні ідеї", які ніколи не бачили прийняття мейнстріму, - це вежа зі слонової кістки, яка не працює в реальному світі. Відсутність популярності, безумовно, не є чітким моментом на користь чого-небудь.
Майкл Боргвардт

10

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

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

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

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

Помилка робить клас або тип одиницею модульності. Це неправильно, і доказово так. Навіть Мейєр визнав проблему (називається проблемою коваріації), що OOP не може обробити відносини аритії вище, ніж одне (тобто, OOP спрацьовує за властивостями, але не справляється з бінарними відношеннями). У Ейфелі ця проблема призвела до розголосу в системі типів!

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

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

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

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

Навряд чи наслідування майже не використовується в бібліотеці шаблонів стандартів C ++.

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


спокусився створити ще один аккаунт, щоб підняти на вас ще декілька;)
Марко Мар'яні

Ви робите ряд тверджень. Можливо, ви можете або надати аргументи, що підтверджують ваші твердження, або посилання на аргументи. На кшталт цього, що не зовсім підтримує ваші різні тези (у сенсі цього сказано: "З OO щось не так; це потрібно зробити"): lucacardelli.name/Papers/BadPropertiesOfOO.pdf
Frank Shearar

3
Говорячи, що "foo - це найбільше зло і погано ...", до речі, є агресивним до будь-якого аргументу, який ви можете спробувати зробити, до речі.
Френк Ширар

6

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

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

http://en.wikipedia.org/wiki/Object-oriented_programming

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


2

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

Існують також інші способи управління складністю програмного забезпечення, наприклад, логічне (Prolog) та функціональне (Haskell) програмування.

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

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


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

2

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

Я віддаю перевагу визначенню, яке надає Ерік Стівен Реймонд у програмі «Мистецтво програмування Unix» , оскільки воно розмежовує між істотною, необов'язковою та випадковою складністю. http://www.faqs.org/docs/artu/ch13s01.html#id2964646

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


2

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

OOP - це технологія, концепція та спосіб підходу до проблеми.

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

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

Зрештою, об'єктно-орієнтоване програмування не може бути вирішенням складності; це просто інструмент управління ним. (при правильному використанні)


+1 Зрештою, об'єктно-орієнтоване програмування не може бути вирішенням складності; це просто інструмент управління ним. (при правильному використанні)
Karthik Sreenivasan

2

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

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

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


1

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

Як часто говорили про C ++, OOP дає вам достатньо мотузки, щоб повіситися.


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

@Michael, Деякі більше, ніж інші. Але по суті, так. Немає срібних куль, завжди є зворотний бік до тієї мови чи парадигми, якою ви користуєтесь.
Домінік МакДоннелл

1

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

Розділяй і володарюй.


1

OOP - це спроба рішення.

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

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

Кінцевим результатом є те, що сучасні програмісти OO в кінцевому підсумку стають "підмайстрами чаклуна", де вони з'єднують купу великих, неграйних бібліотек з кількома рядками "клею" і отримують щось, що працює. Сорта. Свого роду. Більшу частину часу. Чи можливі побічні ефекти від використання цієї бібліотеки з цією? Можливо. Але хто встиг по-справжньому розібратися в коді, що міститься в цих бібліотеках? Особливо, коли бібліотеки розвиваються. У результаті ми закінчуємо роздуті програми, де програмісту потрібно було кілька класів та методів із цієї бібліотеки, але додаток повинен мати вагу всіх інших ДРУГИХ речей, які їм не потрібні.

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

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

Поки вам не доведеться підтримувати щось, що написав хтось інший.

Так, добре знати, що всі функції доступу до даних розташовані тут. Але що їх називає?

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

Ви закінчуєте безліч маленьких, дискретних методів, які роблять точні речі. Але цей називає того, в іншому класі. Що називає того, в іншому класі. Що називає того, в іншому класі. Що називає того, у додатковому класі. Який повертає результат певного типу. На якому ви повинні викликати метод зробити певну справу. Який повертає результат іншого типу. І т.д.

Для цього є термін: код спагетті.

У вас виходить дуже складна система, необхідна просто для створення коду. Звідси такі IDE, як Visual Studio, Eclipse та NetBeans. Усі вони мають значну криву навчання. Дійсно, багато з них здатні інкапсулювати / об'єднати декілька інструментів, розроблених різними групами, кожна з яких має свої власні криві навчання.

Це управління складністю?

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

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

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

Якщо ви вже знаєте, як це працює, і ви можете це пам’ятати, ви можете мати шанс зберегти його.

Не забудьте застосувати Закон Еглсона: будь-який власний код, який ви не переглядали протягом півроку, може бути написаний кимось іншим.


0

Певною мірою ...

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


0

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

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

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


1
Коментарі видалено; намагайтеся тримати їх цивільними.
Fishtoaster

0

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

так, це також рішення складності, надавши вам модель "побачити" ваш код природним чином, як об'єкти, які мають властивості та можливі дії

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