Чистий javascript.Тестування. Форматування. Коментарі

Пропоную читачам «Хабрахабра» переклад книги Райана Макдермота «Clean-code-javascript».

Зміст


Тестування
Тестування дуже важлива частина розробки. Якщо у вас немає тестів або їх недостатньо, як ви можете бути впевнені, що ви нічого не зламаєте? Ваша команда повинна сама приймати рішення за обсягом коду покритого тестами, але чим більше вкрите тестами, тим спокійніше спить розробник. Це означає, що на додаток до наявності хорошого інструменту для тестування, необхідно також використовувати хороший інструмент для перевірки покриття коду тестами. Немає причин не писати тести. Ось добірка гарних інструментів для тестування. Підібравши зручний для вашої команди, пишіть тести для кожного модуля або фічі. Якщо ви вибрали розроблення через тестування (Test Driven Development TDD) -це чудово, але головне полягає в тому, щоб переконатися, що тести покривають всі ваші цілі перед розробкою нового коду, або рефакторінгом існуючого коду.

Один тест — один опис.

Погано:

const assert = require('assert');

describe('MakeMomentJSGreatAgain', () => {
it('обробляє кордону дат', () => {
let date;

date = new MakeMomentJSGreatAgain('1/1/2015');
date.addDays(30);
date.shouldEqual('1/31/2015');

date = new MakeMomentJSGreatAgain('2/1/2016');
date.addDays(28);
assert.equal('02/29/2016', date);

date = new MakeMomentJSGreatAgain('2/1/2015');
date.addDays(28);
assert.equal('03/01/2015', date);
});
});

Добре:

const assert = require('assert');

describe('MakeMomentJSGreatAgain', () => {
it('обробляє додавання 30 днів', () => {
const date = new MakeMomentJSGreatAgain('1/1/2015');
date.addDays(30);
date.shouldEqual('1/31/2015');
});

it('обробляє додавання днів у високосний рік', () => {
const date = new MakeMomentJSGreatAgain('2/1/2016');
date.addDays(28);
assert.equal('02/29/2016', date);
});

it('обробляє додавання днів у звичайний рік', () => {
const date = new MakeMomentJSGreatAgain('2/1/2015');
date.addDays(28);
assert.equal('03/01/2015', date);
});
});


Форматування
Форматування носить суб'єктивний характер. Немає жорстких правил, які ви повинні дотримуватися. Головне правило — не сперечатися з приводу форматування. купа інструментів для автоматизації цього. Використовуйте тільки одну!
Спір з приводу форматування — це марна трата часу і грошей для розробників.

Для речей, які не підпадають під сферу дії автоматичного форматування (відступи, табуляція або пробіли, подвійні або одинарні лапки і т. д.) дивіться якесь керівництво.

Використовуйте один варіант іменування

JavaScript є нетипизированным, тому іменування ваших змінних, функцій і т. д говорить вам багато чого про них. Ці правила носять суб'єктивний характер, так що ваша команда може вибрати той варіант, який хоче. Неважливо який варіант ви виберете, головне дотримуйтесь вашого вибору.

Погано:

const DAYS_IN_WEEK = 7;
const daysInMonth = 30;

const songs = ['Back In Black', 'Stairway to Heaven', 'Hey Jude'];
const Artists = ['ACDC', 'Led Zeppelin', 'The Beatles'];

function eraseDatabase() {}
function restore_database() {}

class animal {}
class Alpaca {}

Добре:

const DAYS_IN_WEEK = 7;
const DAYS_IN_MONTH = 30;

const songs = ['Back In Black', 'Stairway to Heaven', 'Hey Jude'];
const artists = ['ACDC', 'Led Zeppelin', 'The Beatles'];

function eraseDatabase() {}
function restoreDatabase() {}

class Animal {}
class Alpaca {}

Пов'язані функції повинні знаходиться поруч

Якщо функція викликає іншу, збережіть ці функції вертикально близько у вихідному файлі. В ідеалі, функція, яка використовує іншу функцію, повинна бути прямо над нею. Ми схильні читати код зверху-вниз, як газету. З-за цього зручно розміщувати код таким чином.
Погано:

class PerformanceReview {
constructor(employee) {
this.employee = employee;
}

lookupPeers() {
return db.lookup(this.employee, 'вузли');
}

lookupManager() {
return db.lookup(this.employee, 'manager');
}

getPeerReviews() {
const peers = this.lookupPeers();
// ...
}

perfReview() {
this.getPeerReviews();
this.getManagerReview();
this.getSelfReview();
}

getManagerReview() {
const manager = this.lookupManager();
}

getSelfReview() {
// ...
}
}

const review = new PerformanceReview(user);
review.perfReview();

Добре:

class PerformanceReview {
constructor(employee) {
this.employee = employee;
}

perfReview() {
this.getPeerReviews();
this.getManagerReview();
this.getSelfReview();
}

getPeerReviews() {
const peers = this.lookupPeers();
// ...
}

lookupPeers() {
return db.lookup(this.employee, 'вузли');
}

getManagerReview() {
const manager = this.lookupManager();
}

lookupManager() {
return db.lookup(this.employee, 'manager');
}

getSelfReview() {
// ...
}
}

const review = new PerformanceReview(employee);
review.perfReview();


Коментарі

Коментуйте тільки той код, який описує складну бізнес-логіку

Коментарі не обов'язкові. Хороший код описує себе сам.

Погано:

function hashIt(data) {
// хеш
let hash = 0;

// довжина рядка
const length = data.length;

// Прохід по кожному символу даних
for (let i = 0; i < length; i++) {
// Беремо символ.
const char = data.charCodeAt(i);
// Робимо хеш
hash = ((hash << 5) - hash) + char;
// Преобразовуем в 32-бітне число
hash &= hash;
}
}

Добре:

function hashIt(data) {
let hash = 0;
const length = data.length;

for (let i = 0; i < length; i++) {
const char = data.charCodeAt(i);
hash = ((hash << 5) - hash) + char;

// Преобразовуем в 32-бітне число
hash &= hash;
}
}

Не коментуйте непотрібний код

Для цього існують системи контролю версій. Залиште старий код в історії системи контролю версій.

Погано:

doStuff();
// doOtherStuff();
// doSomeMoreStuff();
// doSoMuchStuff();

Добре:

doStuff();

Не ведіть журнал коментарів

Пам'ятайте: треба використовувати систему контролю версій! Немає необхідності в неисполняемом коді, закоментованому коді і особливо в журналі коментарів.
Використовуйте git log, щоб отримати історію!

Погано:

/**
* 2016-12-20: Removed monads, didn't understand them (RM)
* 2016-10-01: Improved using special monads (JP)
* 2016-02-03: Removed type-checking (LI)
* 2015-03-14: Added combine with type-checking (JR)
*/
function combine(a, b) {
return a + b;
}

Добре:

function combine(a, b) {
return a + b;
}

Уникайте позиційних маркерів

Вони, як правило, просто заважають. Нехай функції і імена змінних разом з відповідним поглибленням і форматуванням дають візуальну структуру коду.

Погано:

////////////////////////////////////////////////////////////////////////////////
// Scope Model Instantiation
////////////////////////////////////////////////////////////////////////////////
$scope.model = {
menu: 'foo',
nav: 'bar'
};

////////////////////////////////////////////////////////////////////////////////
// Action setup
////////////////////////////////////////////////////////////////////////////////
const actions = function() {
// ...
};

Добре:

$scope.model = {
menu: 'foo',
nav: 'bar'
};

const actions = function() {
// ...
};

Джерело: Хабрахабр

0 коментарів

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