Коли використовувати ОВП, а коли - ФП?

Коли використовувати ОВП, а коли - ФП?

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


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

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

При ОВП підході програміст складає нові об'єкти і розширює існуючі шляхом додавання до них методів.

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

При ФП підході програміст пише нові функції.

У поєдинку між ведмедем і крокодилом вирішальним фактором виступає місцевість.

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

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

Звичайно, в бізнес-програмуванні домінує функціональна модель. Сюрприз? Сюрприз, якщо ви розглядаєте тільки такі мови, як Java, C++, C # і Ruby.

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

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

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

І тим не менш, ми хапаємося за об'єкти в додатках. Просте слідування моді? Чи є якась фундаментальна різниця між тим, що нам потрібно зробити в додатках, і тим, що нам потрібно зробити при роботі з базою даних?

Відповідь у тому, що просто зробити через ОВП, а що просто зробити в базах даних.

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

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

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

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

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

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

Так що щодо ФП - код, написаний у функціональному стилі? Що щодо простої організації ООП-програм у вигляді набору операцій, що діють над відносно незмінними наборами даних?

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

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

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

Image