З лупою на слона

Я досить давно беру участь у розробці web-додатків. Це не високонавантажених програми (типу Facebook або Gmail) — там, зрозуміло, своя специфіка. Мої додатки були невеликими (можна було вмістити на одному фізичному сервері), але функціонально насиченими — фінансові, e-commerce. Я не працював у великих командах, натомість помацав весь спектр технологій, починаючи від збірки апаратури в стійці і закінчуючи редагуванням CSS.
В якийсь момент зловив себе на думці, що моя діяльність в області розробки web-додатків чомусь почала нагадувати мені полювання моїх далеких предків на мамонта (якщо під мамонтом розуміти завдання, яку потрібно вирішити). Тільки предки покладалися на свою фізичну силу, а ми замість цього використовуємо силу свого інтелекту. Але як і раніше велику здобич не завалити поодинці — потрібні спільні зусилля всіх мисливців.
image
Під катом я спробував зібрати своє бачення щодо найбільш важливих з моєї точки зору аспектах в розробці web-додатків.
Адаптивність
image
найважливіший аспект, IMHO. Сучасні web-додатки повинні еволюціонувати протягом всього свого життя, весь час підлаштовуючись під постійно змінюється навколишнє середовище. І не тільки зовнішній по відношенню до web-додатком світ змінюється весь час, але іноді web-додатки самі своєю появою змінюють навколишній світ. У web-розробці модель водоспаду поступилася місце спіральної моделі не тому, що модель водоспаду погана — вона просто не встигала за змінами. «Водоспад» і зараз хороший для розробки додатків в деяких інших, не таких динамічних середовищах — наприклад, Для марсіанських зондів. У web-розробки ж набагато важливіше зробити додаток, який легко змінювати, ніж додаток, який працює у відповідності з вимогами замовника. Чому так?
Невизначеність
image
Ось відповідь на попереднє питання. Замовник найчастіше сам не може коректно сформулювати свої вимоги до додатка. Буває, що розробка здійснюється при відсутності ясного розуміння, яким повинен бути кінцевий результат — є загальне бачення напрямку руху, і іноді рішення приймаються не "виходячи з попереднього досвіду", а для продукування оного. Після чого подання замовника про прекрасне можуть різко змінитися, а ваші напрацювання — різко втратити актуальність.
Practice makes perfect
image
Коректність вимог, що пред'являються до додатка, може бути підтверджена тільки після деякої обкатки імплементації цих вимог в черговий версії програми. Чим менше часу від формулювання вимоги до використання його імплементації, тим раніше можна оцінити успішність прийнятого рішення.
Іншими словами, стратегія «тяп-ляп — і в продакшн» може бути цілком виправдана, якщо в результаті її використання деякий набір корисного функціоналу зростає, а набір марного, а то й відверто шкідливої функціоналу навпаки — зникає. Зрозуміло, "тяп-ляп стратегія" працює тільки для спіральної моделі розробки і тільки для високо адаптивних додатків. Тому web-додаток повинен потрапляти в альфа-бета-гамма-… експлуатацію якомога раніше, а цикл внесення змін повинен бути як можна коротше.
Там на невідомих доріжках...
image
Чим хороші популярні продукти? Як мінімум тим, що основний функціонал в них не містить помилок, а якщо раптом якісь регресії і вилазять, то про це швидко стає відомо, і їх тут же виправляють. Ось тільки це відноситься тільки до основного функціоналу і тільки до популярних продуктів. Мільйони користувачів крокують по одним і тим же «функціональним стежках», вытаптывая їх до стану асфальту. Але варто звернути з таких стежок трохи вбік і можна загрузнути по горло в болоті навіть в самому популярному продукті.
Як натоптать доріжки в продукт, в якому немає мільйонів користувачів? Самим ставати такими користувачами. Це тільки хороший драгдилер не повинен сам використовувати те, що він продає. Хороші розробники просто "зобов'язані вживати" свій продукт. І не тільки самі розробники — члени їх сімей, друзі, знайомі, знайомі друзів і друзі знайомих. Загалом, всі, до кого можна дотягнутися і у кого є інтернет, всі повинні взяти участь у використанні створюваного web-додатки з як можна більш ранній стадії.
Якщо ж у розробників немає великих соціальних зв'язків, їм доводиться покладатися на Selenium і йому подібні продукти. Сценарії автоматичного тестування цілком можуть замінити невелику юрбу користувачів, але при цьому досить сильно знижують адаптивність самого додатка — доводиться змінювати не тільки функціонал програми, але і сценарії перевірки цього функціоналу.
Обробка помилок
Колись одним з ознак доброго ЩОДО була наявність "захисту від дурня". Існувала думка, що будь-яка послідовність натиснення клавіш на клавіатурі або одночасного натискання будь-якої їх комбінації не повинні призводити до аварійного завершення програми. В силу чого розробнику доводилося думати не лише про те, як обробляти очікувані дані, але і про те, до чого призведе обробка несподіваних даних.
Зараз web-додатки стали настільки багаторівневі, що можна вже не сильно піклуватися про подібному аспекті. Я не маю на увазі, що можна забити на SQL injection або CSRF-атакия лише маю на увазі, що якщо при збереженні в базі даних про нового користувача з якихось причин не надійшла інформація про обов'язкове email е клієнта, немає необхідності формувати user-friendly повідомлення про помилку — досить того винятки, що викине середовище виконання (типу "Integrity constraint violation").
Якщо додаток працює в очікуваному оточенні з очікуваними даними, то подібних помилок не буває. Помилки виникають тоді, коли використовуються несподівані дані або склалося несподіване оточення. У такій ситуації набагато важливіше як можна раніше відреагувати на несподівані дані або несподіване оточення і додати валідацію вхідних даних (валідація — це бізнес-логіка, а не обробка помилок), або ввести обробку несподіваного стану, перевівши його в розряд очікуваних.
Інформація, що передається програмою людям в повідомленні про помилку, повинна в першу чергу бути призначена для людей-розробників, а не для людей-користувачів.
image
Максимальною завданням людини-користувача є створення issue про "якийсь фигне, що сталася при збереженні даних" з додатком скріншота і повідомлення про помилку. А краще навіть цього йому не довіряти — web-додаток і само може рапортувати про несподіваної ситуації і створювати issues для людей-розробників. Людина-користувач буде навіть вдячний, якщо побачить повідомлення типу "сталася якась фігня, розробникам повідомили, що вони вже працюють, як поправлять — стукнуть по email, приносимо свої вибачення за незручності".
Для нього набагато важливіше отримати повідомлення про виправлення заважає йому помилки через розумне час (хвилини, години, дні), ніж детальний опис того, що саме сталося в додатку, і дружелюбне пояснення, чому саме його запит не може бути опрацьований саме в даний момент. Зрозуміло, issues не повинні стояти в черзі тижнями або місяцями — якщо з якихось причин розробникам не вдалося підійти до проблеми протягом, припустимо, півроку, то можна сміливо викидати таку проблему — вона вже неактуальна, повториться пізніше (вже повторилася), створивши новий issue на ту ж тему (і не один).
Орієнтованість на розробника
image
Як я вже зазначив, web-додатки повинні бути адаптивними. Хто не встиг змінитися — вилетів з обойми. Тому web-додатки повинні бути орієнтовані не на кінцевого користувача, не на власника бізнесу, web-додатки насамперед повинні бути орієнтовані на розробника (хто в цьому не впевнений — просто натисніть Ctrl+Shift+I).
Програма підлаштовується під кінцевого користувача не на вимогу власника бізнесу, а тому що його змінив розробник. Чим раніше розробник зрозуміє, де і на що йому потрібно змінити, тим раніше кінцевий користувач отримає те, що на думку власника бізнесу він хоче мати. Тому пріоритетом у web-розробки повинен бути зрозумілий код, а не код минифицированный, код красивий або код быстроработающий.
Зрозумілим код повинен бути не тільки під час його написання, читання, але і під час налагодження, і під час тестування. Це не тільки за минификацию/обфускацію/транспиляцию я зараз кажу, але в тому числі і за безліч точок повернення в методі, і за текучий інтерфейс, і за відсутність ID у значущих елементів DOM'а. Всі ці штучки дуже пожвавлюють і без того цікавий процес налагодження та тестування коду.
Я розділяю поняття «програміст» та «розробник» — хороший програміст не повинен займатися налаштуванням оточення для програми, хороший програміст не повинен читати логи програми і розуміти, "чому в них написано саме те, що в них написано і звідки це могло взятися, якщо цього взятися нізвідки не повинно було", і хороший програміст не зобов'язаний копатися відладчиком в нетрях написаного не їм коду. Це все робота розробника. Саме на нього має бути орієнтоване web-додаток. Більше того, воно повинно бути орієнтоване на
Посереднього розробника
Код, зазвичай, пишеться генієм — творчою особистістю, повністю усвідомлює масштаби розв'язуваної задачі і выхватывающей рентгенівським зором свого розуму її найдрібніші нюанси. А змінюється — людиною, яка не тільки нюансів не вловлює, але навіть не завжди розуміє, для чого цей код писався спочатку. І адже, найчастіше, це один і той же чоловік. Хто пробував змінювати свій код в проекті, до якого не торкався більше півроку, той розуміє, що я маю на увазі.
image
Web-додаток повинен дозволяти модифікувати себе не тільки випав з контексту розробникам, але і тим, хто взагалі не бачить загального контексту задачі. Тому на допомогу посереднього розробнику має йти все — опис бізнес-функцій в коментах коду, що «говорять» найменування для змінних/функцій/класів, структурування файлів проекту і структурування коду в окремому файлі, використання можливостей IDE (inline documentation, autocomplete, hierarchy browsing), крос-посилання на пов'язані з контексту файли (у тому числі і для @deprecated анотацій).
Саме за такі от маленькі «соломинки» хапається «потопає» у модифицируемом коді розробник, коли необхідно в стислі терміни відновити контекст, для якого був створений код, зіставити його з новим контекстом і зрозуміти, які зміни потрібно внести, щоб змінений код почав працювати в новому контексті і не порушив ті області старого контексту, які не перекрилися розглянутої областю нового.
І, зрозуміло, тести — якщо геній подбав про написання тестів, для перевірки своєї реалізації функціоналу, то навіть самий посередній розробник зможе їх запустити і переконатися, що його правки не вплинули на роботу генія.
Модульність
image
Розділення програми на модулі — це принцип, древній як світ. Декомпозиція дозволяє обмежити контекст застосування окремого модуля (модулів), полегшуючи життя посереднього розробнику, і дозволяючи геніям будувати більш складні програмні комплекси. Кожне web-додаток, що претендує на звання складного додатка, так чи інакше складається з модулів. Модуль — це окрема функція або замикання (JS scope), і окремий клас і окремий файл, група файлів з певною структурою, і ця ж група файлів, закатана в архів, і група архівів.
Будь-яке сучасне додаток (не тільки web) залежить від безлічі різних зовнішніх залежностей для роботи з якими придумано безліч інструментів — rpm, dpkg, ant, maven, PEAR composer, npm, requirejs, browserify. Можливо, коли-небудь з'являться репозиторії і для web-модулів — компонентів для побудови web-додатків (плагінів/розширень, а не те, що має на увазі java або requirejs). Поки ж створення чергового web-додатки найчастіше починається з проектування власної структури даних для аутентифікації користувачів.
Тим не менш, чи використовуємо ми сторонні модулі в своєму web-додатку або пишемо свої — але наше додаток цілком і повністю складається з модулів. І чим краще у нас продумана структура модулів, тим більш складні програми можна будувати на їх основі. Найчастіше, для створення дуже складних композицій потрібні дуже прості, навіть примітивні, правила зрозумілі не лише посереднім розробникам, а всім, хто так чи інакше може взяти участь у створенні цієї композиції. Наприклад, двійкова система.
Мурашник
image
Саме правила дозволяють мурашкам співіснувати єдиною спільнотою і зводити конструкції, що перевищують їх зростання в сотні і тисячі разів. Саме правила дозволяють людям створювати програмні комплекси в тисячі разів складніше тих, які могли бути побудовані силами однієї людини.
Ці правила можуть бути оформлені у вигляді стандартів (ISO RFC або оформлені менше формально, або навіть зовсім неформально. Тим не менш саме ці правила дозволяють розробникам взаємодіяти один з одним, будувати свої проекти на базі інших проектів (бібліотеки, фреймворки, связывать одні проекти з іншими проектами. Загальне розуміння правил уможливлює підтримку одними (адміністраторами) додатків, створених іншими (розробниками). Навіть використання додатків вимагає загального розуміння базових правил (хто пробував відкрити файл Ctrl+O IBM Visual Age, а?).
Сучасне web-додаток — це композиція зусиль безлічі «мурашок», велика частина з яких в очі не впадає (починаючи з двійкової системи і аж до браузера). Ми, користувачі, помічаємо тільки кінцеві зусилля конкретних розробників, реалізаторів наших желаний. Ми, користувачі, часто хочемо «щось таке», абсолютно не замислюючись про те стеку технологій, на якому базується програма, про те, що з нами перерахованого робиться в два кліка, а що — з перетрушуванням структур даних. Ми хочемо те, чого немає в інших, нехай і не прямо зараз, але як можна швидше.
І як користувачі ми абсолютно праві в своєму небажанні занурюватися в деталі реалізації, але от як розробники ми повинні розуміти не тільки весь стек використовуваних технологій, але і забезпечити його адаптацію під постійні зміни бажань кінцевих користувачів (або подання замовника web-додатки таких бажаннях). Тобто, розробники на вершині ієрархії «мурашника» (біля кінцевого користувача), повинні не тільки використовувати плоди праці своїх колег на нижніх рівнях, але й повинні мати можливість донести потреби користувачів (feedback) і внести свої корективи в більш нижні рівні.
Спеціалізація, уніфікація, усуспільнення — ось ті кити, які, я сподіваюся, коли-небудь дозволять створити для web-додатків модуль аутентифікації, аналогічний утиліті grep nix-операционках, а створення web-додатків стане більше схожим на компонування linux-дистрибутивів.
Зворотний сумісність
image
А ця главку додана спеціально для майбутніх розробників Magento 3, якщо такі раптом з'являться. Вимогу зворотної сумісності часто повинні задовольняти всі прийняті рішення за проектом. Це якщо і не Священний Грааль, то цілком собі навіть «королівське» вимога. Але… зворотна сумісність — ворог адаптивності. коротко.
Резюме
Сучасне web-додаток:
  • змінюється стільки, скільки існує;
  • є сукупністю зусиль багатьох людей, навіть якщо кінцевим розробником є одна людина;
  • збирається з безлічі модулів, значна частина яких використовується в інших web-додатках;
  • взаємодіє з іншими web-додатками за певними правилами;
  • має бути дуже приязно не тільки до кінцевого користувача, але і до своїх розробникам;
  • не зобов'язана бути сумісним зі своїми попередніми версіями (dependency managers на допомогу, як говориться);
Спасибі тим, хто дочитав. Побутує думка автора може не збігатися з вищевикладеним.
p.s. Чому "З лупою на слона"? Коли занурюєшся в нетрі коду, розглядаєш "під збільшувальним склом" химерні вигини реалізації чергового "слона", так відразу і не зрозумієш, де ти знаходишся — на підставі хобота або в основаниии хвоста.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.