Dijkstra & Design Patterns

Дейкстра има много известни размисли. В On the cruelty of really teaching computer science той твърди, че студенти по компютърни науки трябва да прекарат първите си няколко години далеч от компютри и да се занимават единствено с формална манипулация на символи.

Доналд Кнут е несъгласен (из Coders at Work):

But that’s not the way he [Dijkstra] learned either. He said a lot of really great things and inspirational things, but he’s not always right. Neither am I, but my take on it is this: Take a scientist in any field. The scientist gets older and says, „Oh, yes, some of the things that I’ve been doing have a really great payoff and other things, I’m not using anymore. I’m not going to have my students waste time on the stuff that doesn’t make giant steps. I’m not going to talk about low-level stuff at all. These theoretical concepts are really so powerful – that’s the whole story. Forget about how I got to this point.“

I think that’s a fundamental error made by scientists in every field. They don’t realize that when you’re learning something you’ve got to see something at all levels. You’ve got to see the floor before you build the ceiling. That all goes into the brain and gets shoved down to the point where the older people forget that they needed it.

Това е често срещана история. Протича така:

Човек хваща нещо ново, непознато и нетривиално (например програмиране). Няма опит, не познава скритите мотики и прави тон грешки, очевидни за експерта (например спагети с goto). Още по-лошо, дори не ги осъзнава. Опитният наблюдател (например Дейкстра) се хваща за главата и отсича, че начинащите трябва да се пазят от „опасните“ инструменти (например goto). Впрочем, направо да се забранят. И разбира се, стабилна теоритична подготовка.

Но това не е начина, по който ескперта (например Дейкстра) се е научил.

Което ме навежда на размисли за Design Pattern-и. Няколко познати са ми казвали, че те са опасни, „защото n00b-овете могат лесно да се застрелят с тях“ или „защото им дава нещо, зад което да се крият“. Трудни са, overengineering се прави твърде лесно и ако човек стане pattern happy прави проекта неспасяем.

Хубаво, ама не съм съгласен. По две причини.

Първо, глупакът ще намери начин да се нарани с всякакъв инстумент. Тези доводи могат да се приложат върху всичко. Например автоматизирания refactoring е опасен, понеже прави писането на смотан код лесно. Или тестването е лошо, понеже прави промяната на код времеемка (трябва да променяш и теста). Дори copy/paste е зло, понеже позволява на хората да дублират код по елементарен начин. Виждал съм достатъчно хора, които казват, че /XP|agile|Scrum|TDD|pair programming|collective ownership|refactoring/ е тъпо, понеже са ги виждали приложени тъпо.

А това е жалко. По този начин изхвърляме бебето с мръсната вода. В първата си работа заварих странна форма на XP. Бе неефективна, неразбрана и правеше нещата по глупав начин. Всички я мразеха. Ако се бях повлиял от това, сега щях да твърдя, че XP е тъпо. Но вместо това прочетох книгата и започнах да я прилагам адекватно. И това ме направи порядък по-добър програмист.

„Пазете хората от мощните инструменти, защото могат да си отрежат нещо“ е лоша философия. Това е един от големите проблеми на Java. Езикът е правен така, че абсолютен идиот да не може да се простреля в крака. Предполагам, че това е хубаво за образователни цели. Но за по-сложни проблеми е ограничаващо. Липсата на ред неща (например closures или предефиниране на оператори) предпазва лошите програмисти от глупави грешки, но вързва ръцете на добрите. Не съм съгласен да плащам тази цена.

Второ, аз разбрах ООП-то с Design Patterns. Преди това, за мен то се изчерпваше със C++ и наследяване. От тази книга научих много. Разглеждах pattern-ите внимателно. Търсех принципите, от които авторите са се ръководили. Размишлявах подробно на всяка непозната концепция, като „композиция“, „индиректност“ или „интерфейс“. Четох внимателно. Не ме научи на 27 шаблона, които да прилагам. Научи ме на ценностна система и начин на мислене, с които Ерих Гама и компания са стигнали до тях. Бе безценно.

Учудващо, въпреки рисковата ми група (C++ бе единственият ми ОО език), не изцвъках 17 pattern-а за две седмици. Вместо това започнах да правя по-добър дизайн, защото вече имах ценности и рамки, в които да мисля. Започнаха да ми идват по-добри идеи и да правя по-малко грешки. Цялостно, станах по-добър.

Не мисля, че съм изключението. Сигурно ще кажете „да, но ти си адекватен програмист и затова не си се окепазил“. Хубаво, съгласен съм. Но ако не бях адекватен програмист, можеше да се омажа с всичко. Можех да прочета Кнут и да напълня кода си с AVL дървета, двоични търсения и алгоритми за сортиране. Или, не дай си боже, можеше да прочета Applying UML and Patterns и да почна да строя системи с 90 слоя, задвижвани от XML. Ако човек е неадекватен, ще се омаже и с най-простия инструмент. Или ще го издигне в религия.

И да, направих грешки. Несъмнено съм overdesign-вал. Не съм стигал до крайности, но е имало случаи, в които съм могъл да мина по-просто. Месец по-късно се е налагало да поддържам и съм си вземал поуката. Човек се учи от грешките си. И ако грешките са малки и могат да се допускат контролирано, това е безценен опит.

Така че, моят съвет е: прочетете Design Patterns внимателно. Вникнете в нея. Дръжте я близо до леглото си. Прилагайте идеите в нея. Може да научите много и да станете по-добри. Ще ви даде полезни инструменти.

А ако изпаднете в неизлечима архитектурна астронавтика и Hello world-а ви изглежда така, може би трябва преквалифицирате. Старата мъдрост гласи, че ако имате единствено чук, всичко изглежда като пирон. Това е лоша нагласа за един програмист. Също като тази, в която изхвърляте идеи само защото са опасни в чуждите ръце.

4 thoughts on “Dijkstra & Design Patterns

  1. Това за години теория преди практиката ми се вижда пълна глупост. Аз имам навика първо да чета теория и… обикновено до там си оставам, когато подходя така. Систематизираната суха материя може да те учи на добри неща, но ѝ липсва нещо важно, а именно – мотивът на забавление.

    И е много по-трудно да разбереш за какво всъщност става въпрос като първо четеш вместо да „пипнеш“ въпросната технология/език/пр. … Прекалената прецизност те забива в детайла, но не ти дава общ поглед над нещата. Проблемът е, че като има общ поглед, човек не иска да забие в детайла, защото се чувства „над тези неща“ и изпитва познатите нам чудения от типа „това за какво ми е да го знам“.

    Не мисля, че златната среда се постига лесно. Повечето хора са от втория тип, единици четат много. Още по-трудно ще е в бъдеще, когато се натрупат още и още теория и технологии за изучаване. По-скоро след време хората, заниващи се с „компютърни науки“ и програмистите ще са две отделни направления – както физиците-теоретици и екпериментатори.

  2. Здравей Стефан,

    Случайно попаднах на твоя блог и бих искал да ти благодаря, за това че споделяш открито идеите си, опита си и въобще всичко това, което те вълнува.

    Малко са опитните софтуерни инженери в България, които успяват да са полезни, интересни, мотивиращи и в същото време отворени за нови идеи и корекции. При теб всички тези неща се случват и то по един много естествен начин. Продълважай да бъдеш полезен, интересен, мотивиращ и в същото време отворен за нови идеи и корекции!

    По въпроса за Design Patterns и въобще за развиването на концептуалното мислене. Определено смятам, че преди да започне да развива концептуалното си мислене (било в ООП, Бази Данни, Софтуени Архитектури и т.н.), всеки един разработчик трябва да навлезе(практически) в областта, за която иска да развие съответното концептуално мислене. В противен случай ще сътвори такива „модели“, че след това другите ще се чудят – какво да правят с тях. 🙂

    Design Patterns by Erich Gamma et al. без съмнение е „дълбока“ книга, която изисква сериозно внимание, за да се овладеят добре концепциите на 23-те модела (design patterns).

    Смятам че успехът ти в овладяването на тези 23 модела до голяма степен се дължи и на това, че вече си познавал в дълбочина C++. Просто без познаването в дълбочина на C++ няма как да стане!

  3. Здрасти.

    Всъщност, мисля че може да стане без C++. Или по-точно, концептуалната част може да стане без C++, но книгата не е супер подходяща за това. Има две неща, които са трудни за схващане при pattern-ите – (1) абстрактната идея зад всеки (factory в Python е просто lambda) и (2) как участват в рефакторинга (обикновено не се започва с прилагана на pattern, а се рефакторира към него). Не знам дали си я чел, но Refactoring to Patterns страхотно решава втория проблем. За първия още не съм сигурен.

  4. Все още не съм стигнал до Refactoring to Patterns by Joshua Kerievsky. Ще я прегледам, когато и дойде времето. Благодаря ти за това, че ме насочи към нея. 🙂

    Относно абстрактната идея зад всеки от 23-те модела(design patterns), то всички автори на книги за design patterns, на които съм попадал, посочват Design Patterns by Erich Gamma et al. като първоизточник.

    При имплементацията на design patterns трябва да вземем в предвид и еволюцията на езиците за ООП. Днес един и същ модел (design pattern) може да се имплементира по повече от един начин на един език. Пример C#.

    Например в C#3.0 Design Patterns by Judith Bishop, авторката имплементира някои от моделите (design patterns) изцяло по нов начин, с цел да запознае читателите с някои от новите елементи (features) на езика.

    Така че остава единствено непроменена абстрактната идея (концепцията зад всеки от моделите)!

Вашият коментар

Вашият имейл адрес няма да бъде публикуван.