Истинският повратен момент в проекта настъпи, когато Хари Хокхейзър ми изпрати своя нахвърлян код за препращане на поща към SMTP порта на клиентската машина. Почти веднага осъзнах, че една надеждна реализация на това свойство би превърнала в почти ненужни всички други режими на доставка.
От много седмици човърках fetchmail, най-вече за да добавям разни неща, продължавайки да чувствам, че дизайнът на интерфейса върши работа, но е мърляв, тромав, с много незначителни опции, висящи навсякъде. Особено ме дразнеха опциите за стоварване на изтеглената поща в пощенски файл или към стандатния изход, но не можех да разбера защо.
Това, което видях, когато се замислих за SMTP препращането, беше че popclient се опитваше да прави твърде много неща. Той е бил проектиран да бъде хем агент за пренасяне на поща (MTA - Mail Transport Agent), хем агент за доставяне на място (MDA - Mail Delivery Agent). Чрез SMTP препращането, той можеше да излезе от сферата на MDA и да стане чист MTA, оставяйки доставката на място да бъде свършена от други програми, точно както го прави sendmail.
Защо да се оплескваме с цялата сложнотия по настройването на агент за доставяне на поща или установяването на една пощенска кутия като заключена само за добавяне, щом е почти сигурно, че на първо място порт 25 го има на всяка платформа, която поддрържа TCP/IP? Особено когато това означава, че получената поща ще изглежда като съвсем обикновена, пусната от изпращача SMTP поща, което впрочем е точно това, което искаме.
Тук има няколко поуки. Първо, идеята за SMTP-препращането е най-голямата отплата, която получих от съзнателния ми опит да подражавам на методите на Линус. Един потребител ми даде тази страшна идея -- всичко, което трябваше да сторя, беше просто схвана следствията от нея.
11. Щом нямаш добри идеи, тогава разпознавай добрите идеи на своите потребители. Понякога второто е за предпочитане.
Любопитното е, че вие бързо ще откриете, че ако сте напълно и от все сърце честен за това колко много дължите на другите хора, светът като цяло ще се отнася към вас все едно самите вие сте създали всяка частица от изобретението и сега просто скромничите за своя вроден гений. Всички виждаме колко добре се получи това при Линус!
(Когато се изказвах на Perl конференцията през август, 1997, Лари Уол беше на първия ред. Когато стигнах до горния пасаж, той се обади в религиозно-възрожденски стил: "Кажи го, кажи го, брате!". Цялата аудитория се засмя, защото знаеха, че това се получи също и при създателя на Perl.)
След като няколко седмици движех проекта в същия дух, започнах да получавам подобни похвали, и то не само от моите потребители, но и от други хора, които са го дочули. Скатах настрана малко от тази електронна поща. От време на време си я поглеждам, ако случайно започна да се чудя дали животът ми си е струвал. :-)
Но тук има две по-фундаментални, неполитически поуки, които са общи за всички видове дизайн.
12. Често най-поразителните и новаторски решения идват след откритието, че представата ти за проблема е погрешна.
Аз съм се опитвал да реша грешен проблем, като съм продължавал да разработвам popclient като комбиниран MTA/MDA с всички изчанчени видове доставяне на място. Дизайнът на fetchmail се нуждаеше от основно преосмисляне като чист MTA, като част от нормалния SMTP-говорящ път на Интернет пощата.
Когато удариш на камък при разработка, тогава откриваш, че е трудно да мислиш по-напред от следващата кръпка. Често това означава, че е време не да се запиташ дали разполагаш с правилния отговор, а дали задаваш правилния въпрос. Може би проблемът трябва да бъде преосмислен.
И тъй, аз преосмислих моя проблем. Накратко, правилното нещо, което трябваше да се свърши беше: (1) в общия драйвер да се добави поддръжка на SMTP препращане, (2) то да се установи като режим по подразбиране, и (3) накрая да се изхвърлят всички други режими на доставка, особено възможностите за доставяне във файл и доставяне към стандартния изход.
За известно време се колебаех относно стъпка 3, страхувайки се да не разстроя някои дългогодишни потребители на popclient, зависещи от другите механизми на доставка. На теория, те могат незабавно да превключат към .forward файлове или към техните не-sendmail еквиваленти, за да получат същите резултати. На практика преходът би могъл да бъде объркващ.
Но след като го сторих, ползата беше огромна. Изчезнаха най-претруфените части от кода за доставка. Настройката стана много по-проста -- повече нямаше умилкване около системния MDA и потребителската пощенска кутия, нямаше повече грижи за това дали лежащата отдолу операционна система поддържа заключване на файлове.
Също така изчезна единственият начин да се загуби поща. Ако сте посочили доставка във файл и дискът се препълни, пощата ви се губи. Това не може да се случи със SMTP препращането, защото програмата, която слуша на SMTP порта няма да върне OK, докато съобщението не може да бъде доставено, или поне съхранено за доставка по-късно.
Подобри се и производителността (макар и да не се забелязва при едно единствено изпълнение). Друга незначителна полза от тази промяна беше, че страницата с ръководството стана много по-проста.
По-късно открих, че трябва да върна отново функцията за доставка чрез посочен от потребителя MDA, за да е възможно обработването на някои неясни ситуации, усложнени от динамичния SLIP. Но намерих много по-прост начин да го сторя.
Каква е поуката? Не се колебай да изхвърляш остарелите свойства, щом можеш да го направиш без загуба на ефективност. Антоан дьо Сент-Екзюпери (авиатор и проектант на летателни апарати, когато не е бил автор на класически книги за деца) е казал:
13. "Съвършенството (в дизайна) е постигнато не когато няма какво повече да се добави, а когато няма какво повече да се отнеме."
Когато кодът ви става хем по-добър, хем по-прост, тогава знаете, че е тъй. И в този процес, дизайнът на fetchmail придоби своя собствена идентичност, различна от наследения popclient.
Беше време за смяна на името. Новият дизайн изглеждаше много повече като двойник на sendmail, отколкото стария popclient. И двата са MTA, но докато sendmail избутва и сетне доставя, новият popclient издърпва и доставя. И тъй, след два месеца колебание, аз го преименувах на fetchmail.
В историята за това как SMTP доставката се появи във fetchmail се крие една по-обща поука. Успоредно може да бъде не само отстраняването на грешки. Разработката и (може би в удивителна степен) изследването на пространството на дизайна също могат. Когато начинът ви на разработка е рязко итеративен, разработката и подобряването на софтуера могат да се превърнат в частен случай на отстраняването на грешки, т.е. поправяне на "грешки поради недостиг" в първоначалните възможности или в концепцията за софтуера.
Дори и при едно по-високо ниво на дизайн, може да е много ценно да имаш мисълта за много съразработчици, разхождащи се напосоки из пространството на дизайна около твоя продукт. Нещо като локва с вода, която намира пролука, от където да се процеди, или по-скоро както мравките намират храна -- изследване чрез дифузия, последвано от изследване, опосредявано от мащабируем комуникационен механизъм. Това работи много добре. Подобно на случая с Хари Хокхейзър и мен, някой от вашите съратници може лесно да се добере до огромен пробив наблизо, докато вие сте фокусирали на твърде близък кадър, за да го забележите.