diff --git a/README.md b/README.md index 896175c..8247f63 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Ще одна річ: знання цих принципів не зробить вас миттєво кращим розробником програмного забезпечення, і робота з ними протягом багатьох років не означає, що ви не будете помилятися. Кожен фрагмент коду починається як перший чернетковий варіант, як мокра глина, що набуває своєї остаточної форми. Врешті-решт, ми вирізаємо недоліки, коли переглядаємо код з колегами. Не картайте себе за перші чернетки, які потребують покращення. Натомість критикуйте сам код! -**[⬆ повернутись до змісту](#зміст)** +**[⬆ повернутися до змісту](#зміст)** ## Змінні @@ -55,7 +55,7 @@ function between(value: T, left: T, right: T): boolean { } ``` -**[⬆ повернутись до змісту](#зміст)** +**[⬆ повернутися до змісту](#зміст)** ### Використовуйте вимовні імена змінних @@ -81,7 +81,7 @@ type Customer = { } ``` -**[⬆ повернутись до змісту](#зміст)** +**[⬆ повернутися до змісту](#зміст)** ### Використовуйте однаковий словниковий запас для однакового типу змінних @@ -99,7 +99,7 @@ function getUserData(): User; function getUser(): User; ``` -**[⬆ повернутись до змісту](#зміст)** +**[⬆ повернутися до змісту](#зміст)** ### Використовуйте пошукові імена @@ -121,7 +121,7 @@ const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000; // 86400000 setTimeout(restart, MILLISECONDS_PER_DAY); ``` -**[⬆ повернутись до змісту](#зміст)** +**[⬆ повернутися до змісту](#зміст)** ### Використовуйте пояснювальні змінні @@ -145,7 +145,7 @@ for (const [id, user] of users) { } ``` -**[⬆ повернутись до змісту](#зміст)** +**[⬆ повернутися до змісту](#зміст)** ### Уникайте ментального картування @@ -168,7 +168,7 @@ const subscription = getSubscription(); const transaction = charge(user, subscription); ``` -**[⬆ повернутись до змісту](#зміст)** +**[⬆ повернутися до змісту](#зміст)** ### Не додавайте непотрібний контекст @@ -202,7 +202,7 @@ function print(car: Car): void { } ``` -**[⬆ повернутись до змісту](#зміст)** +**[⬆ повернутися до змісту](#зміст)** ### Використовуйте аргументи за замовчуванням замість короткого зациклення або умов @@ -225,7 +225,7 @@ function loadPages(count: number = 10) { } ``` -**[⬆ повернутись до змісту](#зміст)** +**[⬆ повернутися до змісту](#зміст)** ### Використовуйте enum для документування наміру @@ -277,7 +277,7 @@ class Projector { } ``` -**[⬆ повернутись до змісту](#зміст)** +**[⬆ повернутися до змісту](#зміст)** ## Функції @@ -346,7 +346,7 @@ createMenu({ }); ``` -**[⬆ повернутись до змісту](#зміст)** +**[⬆ повернутися до змісту](#зміст)** ### Функції повинні робити одне @@ -378,7 +378,7 @@ function isActiveClient(client: Client) { } ``` -**[⬆ повернутись до змісту](#зміст)** +**[⬆ повернутися до змісту](#зміст)** ### Назви функцій повинні говорити, що вони роблять @@ -406,7 +406,7 @@ const date = new Date(); addMonthToDate(date, 1); ``` -**[⬆ повернутись до змісту](#зміст)** +**[⬆ повернутися до змісту](#зміст)** ### Функції повинні бути лише на одному рівні абстракції @@ -474,7 +474,7 @@ function parse(tokens: Token[]): SyntaxTree { } ``` -**[⬆ повернутись до змісту](#зміст)** +**[⬆ повернутися до змісту](#зміст)** ### Видаліть дубльований код @@ -584,7 +584,7 @@ function showEmployeeList(employee: Employee[]) { Ви повинні критично ставитися до дублювання коду. Іноді існує компроміс між дубльованим кодом і збільшенням складності через введення непотрібної абстракції. Коли дві реалізації з двох різних модулів виглядають схожими, але живуть у різних доменах, дублювання може бути прийнятним і переважати над витяганням спільного коду. Витягнутий спільний код у цьому випадку створює непряму залежність між двома модулями. -**[⬆ повернутись до змісту](#зміст)** +**[⬆ повернутися до змісту](#зміст)** ### Встановлюйте об'єкти за замовчуванням за допомогою Object.assign або деструктуризації @@ -657,7 +657,7 @@ createMenu({ body: 'Bar' }); Щоб уникнути будь-яких побічних ефектів і неочікуваної поведінки передаючи явно значення `undefined` або `null`, ви можете вказати компілятору TypeScript не дозволяти це. Дивіться опцію [`--strictNullChecks`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#--strictnullchecks) в TypeScript. -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Не використовуйте прапорці як параметри функцій @@ -688,7 +688,7 @@ function createFile(name: string) { } ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Уникайте побічних ефектів (частина 1) @@ -730,7 +730,7 @@ const encodedName = toBase64(name); console.log(name); ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Уникайте побічних ефектів (частина 2) @@ -764,7 +764,7 @@ function addItemToCart(cart: CartItem[], item: Item): CartItem[] { }; ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Не пишіть до глобальних функцій @@ -798,7 +798,7 @@ class MyArray extends Array { } ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Віддавайте перевагу функціональному програмуванню над імперативним @@ -853,7 +853,7 @@ const totalOutput = contributions .reduce((totalLines, output) => totalLines + output.linesOfCode, 0); ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Інкапсулюйте умови @@ -877,7 +877,7 @@ if (canActivateService(subscription, account)) { } ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Уникайте негативних умов @@ -905,7 +905,7 @@ if (!isEmailUsed(email)) { } ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Уникайте умов @@ -970,7 +970,7 @@ class Cessna extends Airplane { } ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Уникайте перевірки типів @@ -1000,7 +1000,7 @@ function travelToTexas(vehicle: Vehicle) { } ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Не оптимізуйте надмірно @@ -1024,7 +1024,7 @@ for (let i = 0; i < list.length; i++) { } ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Видаляйте мертвий код @@ -1057,7 +1057,7 @@ const req = requestModule; inventoryTracker('apples', req, 'www.inventory-awesome.io'); ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Використовуйте ітератори та генератори @@ -1139,7 +1139,7 @@ itiriri(fibonacci()) .forEach(fib => console.log(fib)); ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ## Об'єкти та структури даних @@ -1205,7 +1205,7 @@ const account = new BankAccount(); account.balance = 100; ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Створюйте об'єкти з приватними/захищеними членами @@ -1248,7 +1248,7 @@ class Circle { } ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Віддавайте перевагу незмінності @@ -1346,7 +1346,7 @@ const result = readonlyData(100); result.value = 200; // помилка ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### type проти interface @@ -1404,7 +1404,7 @@ class Square implements Shape { } ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ## Класи @@ -1448,7 +1448,7 @@ class Dashboard { // ... ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Висока згуртованість і низька зв'язність @@ -1528,7 +1528,7 @@ class UserNotifier { } ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Віддавайте перевагу композиції перед успадкуванням @@ -1597,7 +1597,7 @@ class EmployeeTaxData { } ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Використовуйте ланцюжок методів @@ -1679,7 +1679,7 @@ const query = new QueryBuilder() .build(); ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ## SOLID @@ -1734,7 +1734,7 @@ class UserSettings { } ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Принцип відкритості/закритості (OCP) @@ -1827,7 +1827,7 @@ class HttpRequester { } ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Принцип підстановки Лісков (LSP) @@ -1944,7 +1944,7 @@ const shapes = [new Rectangle(4, 5), new Rectangle(4, 5), new Square(5)]; renderLargeShapes(shapes); ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Принцип розділення інтерфейсу (ISP) @@ -2025,7 +2025,7 @@ class EconomicPrinter implements Printer { } ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Принцип інверсії залежностей (DIP) @@ -2122,7 +2122,7 @@ const reader = new ReportReader(new JsonFormatter()); const report = await reader.read('report.json'); ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ## Тестування @@ -2140,7 +2140,7 @@ const report = await reader.read('report.json'); 3. Вам не дозволяється писати більше виробничого коду, ніж достатньо для проходження одного невдалого модульного тесту. -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Правила F.I.R.S.T. @@ -2156,7 +2156,7 @@ const report = await reader.read('report.json'); - **Timely** (Своєчасні) модульні тести повинні бути написані до виробничого коду. Якщо ви пишете тести після виробничого коду, ви можете виявити, що написання тестів занадто складне. -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Одна концепція на тест @@ -2206,7 +2206,7 @@ describe('AwesomeDate', () => { }); ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Назва тесту повинна розкривати його намір @@ -2240,7 +2240,7 @@ describe('Calendar', () => { }); ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ## Асинхронність @@ -2311,7 +2311,7 @@ downloadPage('https://en.wikipedia.org/wiki/Robert_Cecil_Martin', 'article.html' `Promise.all` особливо корисний, коли існує потреба запускати завдання паралельно. `Promise.race` полегшує реалізацію таких речей, як тайм-аути для обіцянок. -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Async/Await ще чистіші за обіцянки @@ -2359,7 +2359,7 @@ try { } ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ## Обробка помилок @@ -2424,7 +2424,7 @@ function calculateTotal(items: Item[]): Failable { Для детального пояснення цієї ідеї зверніться до [оригінального посту](https://medium.com/@dhruvrajvanshi/making-exceptions-type-safe-in-typescript-c4d200ee78e9). -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Не ігноруйте перехоплені помилки @@ -2460,7 +2460,7 @@ try { } ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Не ігноруйте відхилені обіцянки @@ -2501,7 +2501,7 @@ try { } ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ## Форматування @@ -2564,7 +2564,7 @@ type Container = { /* ... */ } Перевагу слід віддавати використанню `camelCase` для змінних, функцій та членів класів. Перевагу слід віддавати використанню капіталізованого `SNAKE_CASE` для констант. -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Функції-викликачі та функції-виклики повинні бути близькими @@ -2653,7 +2653,7 @@ const review = new PerformanceReview(employee); review.review(); ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Організуйте імпорти @@ -2702,7 +2702,7 @@ import { ApiCredentials, Adapters } from './common/api/authorization'; import { ConfigPlugin } from './plugins/config/configPlugin'; ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Використовуйте аліаси TypeScript @@ -2736,7 +2736,7 @@ import { UserService } from '@services/UserService'; ... ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ## Коментарі @@ -2763,7 +2763,7 @@ const isSubscriptionActive = subscription.endDate > Date.now; if (isSubscriptionActive) { /* ... */ } ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Не залишайте закоментований код у своїй кодовій базі @@ -2789,7 +2789,7 @@ type User = { } ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Не ведіть журнал у коментарях @@ -2817,7 +2817,7 @@ function combine(a: number, b: number): number { } ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Уникайте позиційних маркерів @@ -2879,7 +2879,7 @@ class Client { }; ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ### Коментарі TODO @@ -2907,7 +2907,7 @@ function getActiveSubscriptions(): Promise { } ``` -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)** ## Переклади @@ -2929,4 +2929,4 @@ function getActiveSubscriptions(): Promise { Перевірте цю [дискусію](https://github.com/labs42io/clean-code-typescript/issues/15) для отримання додаткових деталей та прогресу. Ви можете зробити неоціненний внесок у спільноту *Clean Code*, переклавши це вашою мовою. -**[⬆ повернутись до змісту](#table-of-contents)** +**[⬆ повернутися до змісту](#table-of-contents)**