Головна » 2013 » Березень » 02 » Як два програміста хліб пекли
17:45
Як два програміста хліб пекли


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

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

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

Саме так, «робився», без уточнення способу виробництва. 

Як же надійдуть наші програмісти? 



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

Маркус робить приблизно те ж. Він створює клас Хліб і клас менеджера з фабричним методом createBread (). 

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

А відразу можна було сказати, що хліб печеться не у вакуумі, а в грубці? Ну гаразд, що ж роблять програмісти? 



Борис перейменовує клас ProductFactory в печі, і виділяє абстракцію - AbstractOven. Щоб було зовсім красиво, він метод createProduct () перейменовує в bakeProduct (). Тим самим Борис в перший раз виконав рефакторинг, застосувавши «виділення абстракції», а так само реалізував шаблон «абстрактна фабрика» точнісінько як він описаний в літературі. Молодець, Борис. 

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

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

Що ж, справедливо. 



Борис, радісно потираючи руки, створює три спадкоємця AbstractOven - ElectricOven, MicrowaveOven і GasOven. А клас Духовка він видаляє за непотрібністю. 

Маркус теж вносить зміни в програму. Він додає в метод createBread цілочисельний параметр ovenType. 

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



Борис абсолютно безпідставно вважає, що джерело газу може бути тільки один. А ДЛЯ Таких випадків Завжди ЕСТЬ Наш улюблену шаблон . Він створює поодинці GasSourceSingleton, а для зменшення зв'язності впроваджує його через інтерфейс GasSource в GasOven. Ура, він застосував впровадження залежності через сетер! 

Скромний від природи Маркус створює речовий приватне поле gasLevel в класі Manager. Природно, доведеться трохи поміняти логіку методу createBread, але що поробиш! 

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

Програмісти теж хочуть їсти, тому беруться за роботу. 



Борис вже починає щось таке відчувати, але зупинитися вже не може. Як грубка дізнається, що саме їй потрібно готувати? Очевидно ж - їй потрібен кухар. І Борис, не довго (а може і довго) думаючи, створює клас Кука. У нього буде метод для приготування, приймає на вхід абстрактну піч - кухар (Оуен: AbstractOwen): Product. Адже це логічно - кухар бере піч, і з її допомогою готує. Потім Борис створює ще кілька спадкоємців класу продукт - торт і пастоподібних, а від пастоподібних успадковує MeatPasty і CabbagePasty. А потім для кожного типу продукту створює окремого кухаря - BreadCook, PastyCook і CakeCook. 

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

У шостий раз приходить менеджер. До речі, те, що він зараз попросить - це не вимога замовника, це його власна ініціатива. Але ж про це ніхто не дізнається, так адже? 
- Нам потрібно, щоб хліб, пиріжки та торти випікалися за різними рецептами. 



«Хм», - вимовляє Борис і згадує про шаблон «будівельник» (разом зі «вільним інтерфейсом» , звичайно ж). Він створює клас рецепт, а до нього - будівельник RecipeBuilder. Рецепт він впроваджує (ВНЕЗАПНО!) в пічку за допомогою сетера setRecipe (рецепт: Рецепт). 

А Маркус (ви не повірите) додає ще один цілочисельний параметр в createBread - рецепт. 

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



Для Бориса це остання зустріч з менеджером, але все ж він з останніх сил вносить зміни в архітектуру. Він виділяє абстрактний клас AbstractHeatingSmth - абстрактне нагріває щось. Для нього він створює фабрику HeatingFactory.Від AbstractHeatingSmth він успадковує ProductOven і Furance. В останнього є фабричний метод makeBrick, що створює екземпляр об'єкту Brick. Але нічого не працює. Читачеві пропонується самостійно знайти помилку в архітектурі. 

У Маркуса теж не все так гладко. Йому доводиться створити вже третій (!) По рахунку клас. Він називає його цегла, і додає в свій менеджера метод makeBrick. 

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

Висновки, які я хочу зробити, напевно, трохи передбачувані. 

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

Підхід Маркуса, звичайно, не дозволяє використовувати модульне тестування, але зате він дає результат набагато швидше, і зміни даються меншою кров'ю. Цей підхід - той самий швидкий старт, якого так хочуть стартапери всіх мастей. І, як не дивно, в такому коді дійсно легше розібратися, тому що він простіший. 
Переглядів: 1004 | Додав: TeMka | Рейтинг: 0.0/0
Всього коментарів: 0
Ім`я *:
Email *:
Код *: