Skip to content

Programming Principles

Принципи програмування

KISS

Принцип Keep It Stupid Simple (Зберігайте це простим, Притримуйтесь простоти) вимагає, щоб код був максимально простим. Чим простіший код, тим легше розібратися в ньому як автору, так і іншим людям, що займаються його підтримкою. Під простотою головним чином розуміється відмова від використання хитрих прийомів та зайвого ускладнення.

Прикладом порушення цього принципу може бути написання окремої функції тільки для виконання операції додавання або використання побітового оператора (зсув вправо >> 1) для ділення цілих чисел на 2. Останнє, безумовно, ефективніше, ніж звичайне (/2), але при цьому дуже знижується зрозумілість коду. Використовуючи такий підхід, реалізовується "розумний кодинг" (clever coding) та надмірна оптимізаціґ (over-optimization). І те, і інше у довгостроковій перспективі не є дуже корисним для підтримки коду.

DRY

Don’t Repeat Yourself (Не повторюйся) - принцип, який полягає в тому, що повторювану дію в коді слід виносити в окрему функцію для можливості багаторазового використання. Треба намагатись уникати однакових фрагментів коду, оскільки це призводить до розсинхронізації. Такий код важко підтримувати в актуальному стані. Також це збільшує кількість коду та кількість необхідних тестів.

Загальне емпіричне правило в інженерії програмного забезпечення, стверджує, що компонент слід випробувати принаймні три рази, перш ніж розглядати створення багаторазового компонента. Також створити багаторазові компоненти втричі важче, ніж створити прості.

YAGNI

You Aren’t Gonna Need It (Тобі це не знадобиться) - принцип, що стверджує, що небажано залишати в програмі "точки розширення" (місця, призначені лише для того, щоб дозволити вам у майбутньому легко додати новий функціонал). Звичайно, це не стосується випадків, коли йдеться про вже запланований функціонал. Такі точки розширення вносять зайву складність та збільшують розмір кодової бази.

SLAP

Принцип Single Level of Abstraction Principle (Принцип єдиного рівня абстракцій) означає, що функції повинні мати єдиний рівень абстракції. Наприклад, функція, яка читає вхідні дані, не повинна також обробляти отримані дані. Для цього вона повинна задіяти окрему функцію, яка знаходиться на іншому, більш низькому рівні абстракції. Чим загальнішою є функція та чим більше інших функцій вона використовує, тим вище вона розташована в абстракційній ієрархії.

GRASP

GRASP (General Responsibility Assignment Software Patterns) — це набір принципів проєктування, які допомагають розподіляти відповідальності між класами та об'єктами у програмному забезпеченні. Вони спрямовані на створення системи, яка легко підтримується, розширюється та розуміється.

За своєю суттю, цей набір патернів більш абстрактний, ніж загально відомий каталог шаблонів від «Банди чотирьох» (GOF-шаблони), та не мають вираженої структури, чіткої області застосування і конкретної розв'язуваної проблеми, а лише являють собою узагальнені підходи / рекомендації / принципи, використовувані при проектуванні дизайну системи. До складу шаблонів GRASP входить 9 шаблонів.

Основні принципи GRASP - Information Expert: відповідальність повинна бути покладена на той клас, який має найбільше необхідної інформації для виконання завдання. - Creator: визначає, який клас повинен створювати інші об'єкти, базуючись на наявних зв'язках між класами. - Controller: встановлює, який клас відповідає за обробку запитів і управління потоками в системі. - Low Coupling: зменшує залежність між класами, що спрощує підтримку та тестування. - High Cohesion: заохочує концентрацію відповідальності в межах одного класу, що робить його більш зрозумілим та функціональним. - Polymorphism: забезпечує можливість використання спільного інтерфейсу для різних типів об'єктів, дозволяючи динамічне виконання методів. - Pure Fabrication: введення штучного класу для зниження зв'язності або підвищення узгодженості. - Indirection: використання посередника для зменшення залежності між компонентами. - Protected Variations: захищає систему від змін у компонентах, використовуючи абстракції.

Приклад реалізації Information Expert

class Order:
    def __init__(self, items):
        self.items = items

    def calculate_total_price(self): # Order is the Information Expert as it knows about its items        
        return sum(item.price for item in self.items)

class Item:
    def __init__(self, name, price):
        self.name = name
        self.price = price

items = [Item("Apple", 1.5), Item("Banana", 0.5)]
order = Order(items)
print(order.calculate_total_price())  # Output: 2.0

TDD Test driven development

TDD (Test driven development) – це методологія розробки програмного забезпечення, яка ґрунтується на написанні тестів перед написанням коду. Це дозволяє писати якісніший код, який легше підтримувати та змінювати.

Коли програмісти використовують TDD, вони пишуть тести, які перевіряють, чи код працює правильно. Потім вони пишуть код, який проходить випробування. Цей процес повторюється доти, доки всі тести не проходять.

Переваги TDD полягають у тому, що він дозволяє програмістам швидко виявляти та виправляти помилки, робить код більш надійним та зменшує кількість помилок у продукті. Крім того, TDD допомагає програмістам краще розуміти вимоги до коду та покращує комунікацію в команді розробки.

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

TDD особливо корисний при написанні додаткового функціоналу до вже існуючого коду, або при виправленні багів, оскільки ми спочатку пишемо тести, які падають, а потім відповідний код, який це виправляє.