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

«Usability коду» звучить добре, назва притягує, ще мені подобається «ергономіка коду», теж відмінно

Ну що ж, поняття юзабіліті коду я вкладаю кілька речей:

  • Дотримання стандартів кодування
  • Відсутність надмірності в коді і коментарях
  • Передбачуваність коду
  • Підтримка читання коду на рівні «зрозуміло і чайнику»
  • Час, необхідний для вивчення коду до рівня «розумію де баг дивлячись на скріншот»
  • Швидкість розробки при повторному використанні коду і дотримання прийнятих норм і стандартів

Думаю, варто трохи зупинитися на кожному.

Стандарти кодування

Тут обговорювати нічого, ти або їх дотримуєшся (хоча б свої, але краще прийняті в своєму середовищі), або ти тут тимчасово, і нікому не будеш потрібен.

Надмірність коду

Іноді, ганяючись за красою ООП ми приходимо до дуже громіздким рішень:

$file = Application::getInstance()->getRequest()->getFiles()->get($filename);

По суті — думаю кожному зрозуміло що робить дана рядок коду, але чому ж не замінити її на просту функцію? Чого боїтеся?

$file = getRequestFile($filename);
// процедурне програмування відстій, бла-бла-бла
$file = Request::getFile($filename);
// вивчи ще патерни
// …

Баланс на межі

Існує думка, що коментувати добре читається код не варто і так всім все зрозуміло, але мені в це слабо віриться, так що я тут кілька тез написав:

  • Відсутність коментарів в коді — погано
  • Правильне іменування змінних в коді — добре
  • Багато коментарів з прогнозом погоди — погано

Що ж добре? Ось тут начебто баланс вдалося дотриматися:

/**
* Check-in user location to DB
*
* Location::checkinUser($User, 2.123654, 0.456321)
*
* @param User $User
* @param float $lat latitude
* @param float $long longitude
* @return bool
*/
function checkinUser(User $User, $lat, $long) {
return Db::insert(“checkin”, array(
‘userId’ => $User->id,
‘lat’ => $lat,
‘long’ => $long
));
}

В даному прикладі намагався вмістити все, що потрібно: однозначні імена методів і змінних, мінімум коментарів, яких вистачає для створення документації за проектом, та підказок в IDE (що важливо!).

Бути провидцем

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

Читаність коду

Чого я хочу від читабельного коду? Це щоб будь-розробник «зі словничком» міг прочитати будь-яку ділянку вашого коду. Я можу не знати JAVA, Python, або ще з десяток мов, але у мене є знання про PHP і JavaScript, я і повинен взявши на озброєння щось типу «RoR для чайників» в якості словника і почати працювати в проекті через день (ну вже краще «Rails for PHP Developers», але це дрібниці).

Не повинно бути магії по шпаргалках — «дістати об’єкт не знаю де, викликати метод не знаю як»:

// привіт ZF
public function errorAction()
{
// магія тут
$errors = $this->_getParam(‘error_handler’);
// а тут правдоподібно
$this->getResponse()->setHttpResponseCode(404);
// ні добре, ні погано, але всі в курсі
$this->view->message = ‘Page not found’;
}

В ідеалі, читаність коду повинна бути на рівні псевдокода.

Ще є така хвороба — коли з шаблонів проектування знаєш лише singleton, звичайно ж це погано, але ось юзабельность коду, якщо його застосовувати з розумом, дуже навіть нічого:

// тут без коментарів зрозуміло що відбувається
$id = Application::getRequest()->getParam(‘id’);
// і тут
$User = UserManager::getById($id);

Де баг?

MVC дуже правильний патерн для веб додатків, він зручний і все таке інше — імхо, цілком юзабельний. Але от біда, у великому додатку контролерів багато, і з цієї причини з’явилася тенденція об’єднувати їх в модулі (що цілком логічно), а самі контролери бити на дій (що можливо надлишково). Таким чином контролер став складовим, і знайомий нам по багатьом фреймворкам — модуль/контролер/екшен. Все добре, та URL до такого контролера виглядає адекватно і читається легко, але прийшли вимоги, і нам доводиться писати правила-роуты, і тепер URL потрібної сторінки став зовсім неоднозначним для нас. Отже треба проглянути всі ці роуты, які, можливо, розфасовані по модулям, чи ще куди, та ялинки ж палиці…

До чого я це все розповідаю? Та до того, що чим більше дій мені треба виконати для локалізації помилок в програмі, тим менше мені такий код подобається. Бачу баг, знаю до файлу і навіть рядки, де шукати — відмінний результат.

Час — гроші

Час витрачений безпосередньо на сам кодинг оцінюють в 30%, але це при проектуванні «до коми», але як-то посидючості у нас не вистачає, не наш метод. З цієї причини варто писати зручний код:

// можемо ж, мляяяять
$bootstrap = $application->getBootstrap();
$bootstrap->bootstrap(‘db’);
$dbAdapter = $bootstrap->getResource(‘db’);
$dbAdapter->getConnection()->exec($dataSql);
// але якось зручніше
$application->getDb()->exec($dataSql);

Якщо розширення функціоналу призводить до копі-пасту — WTF man?

Замість висновків

Якби розробники фреймворків думали не про красу ООП, а про ергономіці коду, то таких популярних і зручних фреймворків як jQuery було б більше 🙂

P. S. В обов’язковому порядку, продумати юзабіліті коду необхідно всім, хто збирається розробляти іль модифікувати черговий фреймворк, адже зручний інструмент завжди знайде свого майстра.

P. P. S. По темі знайшов лише одну статтю — Introducing Code Usability, можливо хтось підкаже ще?

P. P. P. S. Насварив ZF, похвалив jQuery — OK