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


30

Фон

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

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

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

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

Що тут відбувається? Чи погано розроблена будь-яка система, над якою я працював (принаймні з цього погляду)?

Моя філософія

Коли я розробляю програмне забезпечення, я відчуваю, що намагаюся слідувати філософії, яку я відчуваю, тісно пов'язана з філософією ArchLinux :

Arch Linux зберігає властиві їм системи GNU / Linux, зберігаючи їх добре організованими та прозорими. Розробники та користувачі Arch Linux вважають, що спроба приховати складності системи насправді призводить до ще більш складної системи, і тому її слід уникати.

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

Питання на серці

  1. Чи є реальна цінність у приховуванні деталей?
  2. Хіба ми не жертвуємо прозорістю?
  3. Чи не є ця прозорість цінною?

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

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

4
Ви впевнені, що використовуєте правильне визначення "приховування деталей"? У цьому контексті мова йде про зменшення зв’язки , а не про те, щоб не заважати вам вивчати внутрішню роботу чогось.
Андрес Ф.

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

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

Відповіді:


47

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

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

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

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

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


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

3
@ User606723: Так має бути. Це не означає , що вона завжди є . Деякі люди не розуміють сенсу, і вони просто купують більше шарів на більше шарів і перетворюють речі в безлад. Ось чому досвідчені програмісти радять новішим розробникам ніколи не застосовувати нову технологію чи техніку, поки вони не зрозуміють її.
Мейсон Уілер

3
@ user606723: Прозорість спонукає до міцної зв'язку, тому, можливо, це не завжди погано, але зазвичай так є.
Мальфіст

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

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

16

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

Суть абстракції полягає в тому, щоб зняти необхідність запитувати "як це реалізується?". Коли ви телефонуєте user.get_id(), ви знаєте, що це id- те, що ви збираєтеся повернути. Якщо ви повинні запитати "як це отримати ідентифікатор користувача?" то, ймовірно, вам або не потрібен id, або get_id()повертається щось несподіване і погано розроблене.

Ви використовуєте абстракцію, щоб дозволити проектувати:

a house with doors and windows

не дизайн

a box with four walls,
    with 3 holes,
        two of which fit panes of glass surrounded by wood frames,
        one that fits a large plank of wood with hinges and a metal knob,
etc.

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

9
@ user606723 Тоді ваше питання стосується надкомплексного дизайну, а не абстракцій
Андрес Ф.

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

це питання слід закрити або назву змінити
Джейк Бергер

8

Чи є реальна цінність у приховуванні деталей?

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

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

Люди мають обмежену робочу пам’ять. Абстракція дозволяє міркувати про великі системи.

Aren't we sacrificing transparency?

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

for (i = 0; i < pilgrim.wives.size(); ++i) {
  wife = pilgrim.wives[i];
  for (j = 0; j < wife.sacks.size(); ++j) {
     sack = wife.sacks[i];
     for (k = 0; j < sack.cats.size(); ++j) {
        cat = sack.cats[k];
        for (m = 0; m < cat.kits.size(); ++m) {
           ++count;
        }
     }
  }
}

і думаючи "о так, ще чотирирівнева петля над комплектами", а не бачити

pilgrim.kits.each { ++count; }

Чи не є ця прозорість цінною?

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


7

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

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

  • Коли ви знайдете та виправите помилку, вона, ймовірно, існує і в інших копійованих примірниках подібного коду, тому, крім пошуку та виправлення помилки, вам також доведеться піти на полювання на інші події та виправити їх.
  • Щоб знайти помилку або здійснити зміну, програміст з технічного обслуговування повинен мати можливість зрозуміти відповідний код. Складність у цьому збільшується із розміром відповідного розділу коду, але ще більше з його обсягом. Тримати в голові півдесятка змінних, подумки переступаючи якийсь код, доцільно; але якщо у вас їх декілька сотень, на вашу продуктивність сильно впливає (я люблю порівнювати процес роздумів з програмою, яка закінчується фізичною оперативною пам’яттю і повинна зануритися в свопфайл: замість того, щоб читати код за один раз , програміст повинен стрибати вперед і назад, щоб переглянути речі).
  • Обсяг фрагмента коду також впливає на розмір бази коду, яку потрібно викопати, щоб знайти помилку. Якщо у вас є десятирядкова функція з двома параметрами, а глобалів немає, і ви знаєте значення вхідних даних і рядка, на якому вона виходить з ладу, пошук помилки зазвичай тривіальний і часто не вимагає нічого іншого, як дивитися на код. Якщо це кілька сотень рядків, двадцять параметрів, п’ятнадцять глобалів і викликає кілька інших функцій подібного характеру, вас чекає серйозна біль.
  • Без належної абстракції будь-яка зміна може потенційно вплинути на великі частини кодової бази, оскільки практично що-небудь може залежати від коду, який потрібно змінити. Типовий симптом таких кодових баз полягає в тому, що ви робите невелику, здавалося б, невинну зміну, і абсолютно неспоріднена особливість раптово порушується. За допомогою абстрагування ви можете обмежити кількість збитків, які може заподіяти зміна, і ви зробите вплив більш передбачуваним. Якщо ви зміните ім'я приватного поля, у вас є лише один вихідний файл для перевірки; якщо ви зміните ім'я глобальної змінної, вам потрібно пропустити всю кодову базу.

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


2

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

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


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

1
Чи бачите ви зміни коду для кожної основи, яку ви коли-небудь використовували?
JeffO

1
ні, але я не підтримую зміни коду для кожного фрейму, який я коли-небудь використовував.
user606723

3
Ви в значній мірі довели думку Джеффо: ви також не займаєтесь обслуговуванням будильників. Якщо ви купуєте та починаєте використовувати його, не роблячи повної розбивки та аналізу того, як він працює, ви визнали, що нутрощі будуть для вас абстрактними. Ніщо не говорить про те, що ви не можете розірвати його, щоб дізнатися, як це працює, але як часто ви вважаєте це необхідним?
Blrfl

2

Щоб відповісти на ваші запитання конкретно:

Чи є реальна цінність у приховуванні деталей?

Так. Як ви визнаєте в першому рядку свого питання.

Хіба ми не жертвуємо прозорістю?

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

Чи не є ця прозорість цінною?

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


Нарешті, мені подобається відповідь.
користувач606723

1

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

Наприклад, скажімо, ми розробляємо інтерфейс, який визначає поведінку (тобто GetListItems, SendListItem), які є двома функціями, які ініціюються користувачем за допомогою деякого натискання кнопки чи чогось іншого. ЗАРАЗ, кожен користувач може мати свій власний "ListItemStore". Скажімо такі у facebook, ті в myspace .. (наприклад) .. і скажіть, що це збережено як власність / налаштування користувача десь у додатку через налаштування користувачів .. і скажіть, що розробники додатків можуть додавати додаткові ListItemStore протягом курсу час (моя книга, область обличчя тощо)

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

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

тому при використанні коду це щось на зразок:

    new ItemManager(user) //passes in user, allowing class to get all user properties
    ItemManager.GetListItems()

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

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


Так, але частина, яку потрібно підтримувати, ніколи не є тими двома рядками. Це неможливо викрутити. Це завжди потрібно 2-го, 3-го, 4-го рівня, яке потрібно змінити. Я погоджуюся, що це чудово, коли у вас є API, якому ви можете довіряти, щоб він був стабільним , але що робити, якщо він не може бути стабільним лише через складність вашого бізнесу?
користувач606723

1
@ user606723 якщо API не стабільний, то він, ймовірно, або незрілий, або, швидше за все, неправильна абстракція
sdg

@ user606723 - Це правда, і в тих випадках, імена конвенцій самі повинні визначати певну форму прозорості, яка приховує фактичну логіку / деталізацію програмування. тому, по суті, прозорість може бути досягнута за допомогою правильного іменування до кінця вниз, однак, нам не потрібно дуже часто йти по всьому.
hanzolo

@sdg або тому, що вимоги системи завжди змінюються. Тому що закони змінюються, оскільки змінюються API інших, це поза нашим контролем.
user606723

1
@ user606723 - я фактично працюю над фінансовою системою SaaS, і я бачу підводні камені недостатнього абстрагування кожного циклу випуску. Деякі з них є результатом поганого дизайну, але зазвичай це результат введення коду, де він не був призначений спочатку. Спускатися по ланцюгу може бути болісно без цих коментарів, імен та інкапсуляції . якби все, що мені довелося зробити, це Remeasurements.GetRemeasureType (грант), а потім reMeasure.PerformCalc (), це було б набагато приємніше, ніж додавання перевантажень і читання різних логічних гілок, щоб прийти до правильного обчислення або додати нову
hanzolo

1

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

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

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


1

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

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

Припустимо, у вас є вимога, коли користувачі хочуть мати можливість експортувати дані з екрана в різних форматах: обмежений текст, excel та pdf. Хіба не зручно, що ви можете створити інтерфейс під назвою "Експортер" методом експорту (даних), на основі якого ви можете побудувати DelimitedTextExporter, ExcelExporter та PDFExporter, кожен з яких знає, як створити конкретний вихід? Необхідно знати лише програму, що викликає, - це те, що вона може викликати метод експорту (даних), і будь-яка реалізація зробить свою справу. Більше того, якщо змінити правила з обмеженим текстом, ви можете змінити DelimitedTextExporter без того, щоб возитися з ExcelExporter, можливо, порушивши його.

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


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

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

1

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

Я працював з розробниками Java, які перетворили 50 клас кодового рядка в 3 класи та 3 інтерфейси, тому що це легко зрозуміти. І я не витримав.

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

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

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

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


1

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

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

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


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


0

У багатьох випадках вам просто не потрібно знати, як реалізуються речі. Я майже можу гарантувати, що ви будете писати такий код people.Where(p => p.Surname == "Smith")так багато разів на день, але навряд чи колись подумаєте, "як цей Where()метод працює насправді?" Вам просто байдуже - ви знаєте, що цей метод є і що він отримує потрібні вам результати. Чому б вам було байдуже, як це працює?

Це точно так само для будь-якого внутрішнього програмного забезпечення; тільки тому, що це не написано Oracle, Microsoft тощо, не означає, що вам доведеться шукати, як це реалізується. Ви можете обґрунтовано очікувати, що метод, який викликається, GetAllPeopleWithSurname(string name)поверне вам список людей, які мають це прізвище. Це може повторити список, він може використовувати словник, він може зробити щось абсолютно божевільне, але вам просто не повинно бути байдуже .

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

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


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

Проблема в тому, щоPeopleFactory.People.Strategy.MakePeople.(CoutryLaw.NameRegistry.NameMaker.Make()) as People.Female
Coder

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

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

0

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

Ці ідеї виражаються через три основні закони в архітектурі програмного забезпечення:

Закон Саймона: "Ієрархії зменшують складність". (Ієрархії вводять абстракцію)

Закон Парна: "Тільки те, що приховано, можна змінити без ризику".

Закон Костянтина: Надійна програма потребує низької зв'язку та високої згуртованості


"Ієрархії зменшують складність." - не обов'язково правда.
Кодер

Жодна методологія проектування не є детермінованою. Цей закон не походить від ІТ / КС, він формулюється в набагато ширшому сенсі, його також посилають математика, фізики тощо. Це дійсний принцип, але ніхто не може перешкодити вам створити безглузді ієрархії.
ins0m

0

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

Коли я підтримував велику та складну заяву на охорону здоров'я, тобі просто сподобався, я ненавидів усі там абстракції. З'ясовуючи, куди йде весь код, був біль у шиї. Стрибки навколо різних занять мене запаморочили. Тому я сказав собі: "абстракція смокче, я зведемо до мінімуму абстракцію, коли будувати речі".

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

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

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

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


0

Як говорили інші, "приховування деталей" за абстракцією дозволяє змінювати їх, не впливаючи на користувачів. Ця ідея походить від « Критерії Парнаса», які слід використовувати в системах декомпозиції в модулі (1972) , і пов'язана з ідеєю абстрактних типів даних (ADT) та об'єктно-орієнтованого програмування.

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

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

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

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

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


0

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

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

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

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

Наприклад: Використовуючи абстракцію класу Socket на Java, я впевнений, що мій код програми з Java 1.2 все ще працює добре під Java 7 (хоча можливі зміни в продуктивності). З Java 1.2, безумовно, з’явилося багато нових клієнтів, які також використовували цю абстракцію.

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

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

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


0

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

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

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

Інкапсуляція / приховування інформації дозволяє менталітету "не байдуже, як це робиться, просто дбайте про те, щоб це зробити". Ваш об’єкт повинен викрити те, що корисно споживачеві, таким чином, що споживач може легко споживати. Тепер, у реальному світі, це не означає, що автомобіль не повинен давати користувачеві ніякої інформації про внутрішні робочі місця або що машина повинна дозволяти користувачеві лише найосновніші функції, такі як запалювання, кермо, і педалі. У всіх автомобілях є спідометри та датчики палива, тахометри, ідіотні ліхтарі та інші відгуки. Практично всі автомобілі також мають вимикачі для різних незалежних підсистем, наприклад, фари, поворотники, радіо, регулювання сидіння тощо. Деякі машини дозволяють отримати досить езотеричний вхід користувача, наприклад, чутливість центрального диференціала з обмеженим ковзанням. У всіх випадках, якщо ви досить знаєте, ви можете відкрити його та змінити речі, щоб змусити його працювати трохи по-іншому. Але, в більшості випадків, можливо, просто можливо, користувач не повинен мати можливість безпосередньо та незалежно керувати паливними насосами зсередини кабіни? Можливо, просто, можливо, користувач не повинен мати можливість вмикати гальмівні світильники, фактично не натискаючи педаль гальма?

Абстракція дозволяє «це не те саме, що це, але оскільки вони обидва XI, можна використовувати їх так, як я б хотів будь-який X». Якщо ваш об'єкт успадковує або реалізує абстракцію, ваші споживачі повинні розраховувати, що ваша реалізація дасть такий самий або подібний результат, як і інші відомі реалізації абстракції. Toyota Camry та Ford Fusion - це "машини". Таким чином, вони мають загальний набір очікуваних функціональних можливостей, наприклад, кермове колесо. Поверніть його проти годинникової стрілки, машина їде ліворуч. Поверніть його за годинниковою стрілкою, машина їде праворуч. Ви можете зайти в будь-який автомобіль в Сполучених Штатах і очікувати, що у машини буде кермо і принаймні дві педалі, одна справа правою педаллю "їде машина", а друга в центрі - педаль "зупинки машини" .

Слідство абстракції - це "теорія найменшого здивування". Якщо ви сіли за кермо нового автомобіля на тест-драйв, повернули кермо за годинниковою стрілкою і автомобіль повернув ліворуч, ви були б здивовані як мінімум. Ви звинуватили б дилера в тому, що він розглядає POS, і навряд чи вислухаєте будь-яку з його причин, чому нова поведінка "краща", ніж те, до чого ви звикли, або наскільки добре ця поведінка "задокументована" чи як " прозора "система управління є. Незважаючи на цей новий автомобіль та всі інші, якими ви керували, як і раніше залишаються «машинами», під час руху цього автомобіля вам доведеться змінити деякі основні поняття того, як слід керувати автомобілем, щоб успішно керувати новим автомобілем. Це, як правило, погано, і це відбувається лише тоді, коли є нова інтуїтивна перевага перед новою парадигмою. Можливо, додавання ременів безпеки є хорошим прикладом; 50 років тому ви щойно приїхали і поїхали, але тепер вам доведеться загнутися, інтуїтивна перевага полягає в тому, що ви не потрапляєте через лобове скло або на місце пасажира, якщо потрапите в ДТП. Вже тоді водії чинили опір; багато власників автомобілів вирізали ремені безпеки з машини, поки не було прийнято закони, що вимагають їх використання.

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