Чи може занадто велика абстракція бути поганою?


46

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

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

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

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

Примітка: мова не йде про читабельність коду! Обидва коди в 1 і 2 читаються, але код у 2 є більш складними абстракціями, а код 1 - простими абстракціями.


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

25
"Занадто багато" є поганим за визначенням.
Джон Перді,

@JimmyHoffa: Треба зберегти ці типи на своєму місці. І не варто заздрити - мені не вдається писати Haskell цілий день. В основному це PHP, JavaScript і OCaml.
Джон Перді,

Відповіді:


78

Найперші слова TC ++ PL4:

Усі проблеми інформатики можуть бути вирішені іншим рівнем непрямості, за винятком проблеми занадто великої кількості шарів непрямості. - Девід Дж. Вілер

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


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

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


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

1
пробачте моє незнання, але я не розумію "TC ++ PL4"
LastTribunal

30

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

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


1
"А це означає, що в якийсь момент кожна абстракція певним чином просочиться.": Правда. Краща абстракція - це те, що протікає рідше.
Джорджіо

11
Зважаючи на відповідь Б'ярна (і посилання на сторінку вікі Девіда Уілера ), можливо, ви можете змінити атрибуцію вашої цитати? :)
congusbongus

2
@CongXu: Btw Я пішов на це з іншого кінця: гуглінг за "Цитатами Bjarne Stroustrup" і не знайшов жодної посилання на Bjarne, вимовивши фразу "додавання ще одного шару непрямості" ... Не безперечно, звичайно зробити це малоймовірним, що він першим виголосив це.
Мар'ян Венема

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

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

15

Так абсолютно.

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

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

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

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

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

Повернення до теми.

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

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

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

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


2
+1 за "Добрий кравець не залишає шматочки тканини на кожному шві, лише якщо у вас трапиться третя рука або завагітніє". Ми часто схильні проектувати програмне забезпечення таким чином.
Kemoda

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

13

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

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

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