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

Парадигмы программирования

Парадигма программирования — это стиль или подход к написанию программ.

Декларативное и императивное программирование

Императивное программирование

  • Основывается на последовательности команд, которые изменяют состояние программы.
  • Используются конструкции if, for, while, переменные и изменения состояния.
  • Максимально приближено к машинному коду.
  • Пример: C, Go.

Декларативное программирование

  • Описывает, что должно быть сделано, а не как.
  • Используются высокоуровневые абстракции и функции.
  • Максимально приближено к человеческому языку.
  • Пример: SQL, HTML.

Функциональное и процедурное программирование

Функциональное программирование

  • Основной элемент — функции без побочных эффектов.
  • Использует неизменяемые данные и композицию функций.
  • Пример: Haskell, частично Go (через замыкания).

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

  • Основной элемент — процедуры (функции).
  • Использует последовательность вызовов процедур.
  • Пример: C, Pascal.

Отличие между функциональным и процедурным программированием в том, что функциональное программирование ориентировано на чистые функции, которые не изменяют состояние программы, в то время как процедурное программирование может содержать различные side effects. Так же, в функциональном программировании функции могут быть переданы в качестве аргументов другим функциям, а также возвращены из функций.

Объектно-ориентированное программирование

3 основных столпа ООП:

  • Наследование - в Go наследование можно реализовать через встраивание структур. В основном не используется наследование, а используется композиция.
  • Инкапсуляция - инкапсуляция это не только модификаторы доступа, но и способность сущности включать в себя другие сущности и объекты.
  • Полиморфизм - в Go полиморфизм реализуется через интерфейсы. Полиморфный объект может принимать разные формы, например разные реализации интерфейса для базы данных, например для mongoDB и PostgreSQL, но при этом иметь одинаковый интерфейс.

Go Idioms

Go придерживается своих идиом и простоты. Ключевые аспекты:

  • Context — используется для передачи сигналов отмены и дедлайнов в горутины.
  • Error Handling — ошибки возвращаются как значения, что делает обработку ошибок явной.
  • Интерфейсы — описывают поведение через набор методов (io.Reader, fmt.Stringer).
  • Каналы — основное средство коммуникации между горутинами.

https://go.dev/doc/effective_go

Concurrency vs Parallelism

  • Concurrency (Параллелизм задач) — управление несколькими задачами, которые могут прерывать друг друга (Go активно поддерживает).
  • Parallelism (Физический параллелизм) — выполнение нескольких задач одновременно (требует многопроцессорной среды).

Concurrency в Go:

  • Используются горутины и каналы для работы с конкурентными задачами.

Паттерны проектирования

https://github.com/AlexanderGrom/go-patterns

Что такое паттерны проектирования?

Паттерны проектирования - это решения часто встречающихся проблем по шаблону(паттерну) при разработке программного обеспечения. Паттерны проектирования не являются законченными решениями, которые можно просто скопировать в свой проект, они являются обобщенной конструкцией решения проблемы и могут быть использованы в различных ситуациях.

Какие бывают паттерны проектирования?

Паттерны проектирования можно разделить на три группы:

Порождающие паттерны - отвечают за создание объектов.

  • Абстрактная фабрика
  • Строитель
  • Фабричный метод
  • Прототип
  • Одиночка
  • Объектный пул

Структурные паттерны - отвечают за построение удобных в поддержке иерархий классов.

  • Адаптер
  • Мост
  • Компоновщик
  • Декоратор
  • Фасад
  • Приспособленец

Поведенческие паттерны - отвечают за эффективную организацию взаимодействия между объектами программы.

  • Цепочка обязанностей
  • Команда
  • Итератор
  • Посредник
  • Хранитель
  • Наблюдатель
  • Состояние
  • Стратегия

Каждый паттерн нужно знать, что он означает и в каких случаях его можно использовать. Не нужно запоминать все паттерны, достаточно знать, что они есть и где их можно применять.

KISS, SOLID, DRY, YAGNI

Это четыре популярных принципа, используемых в программировании и разработке программного обеспечения, чтобы создавать более читаемый, поддерживаемый, масштабируемый и эффективный код. Вот они:

KISS (Keep It Simple, Stupid):

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

SOLID:

SOLID - это аббревиатура, представляющая пять основных принципов объектно-ориентированного программирования (ООП):

  • S - Принцип единственной ответственности (Single Responsibility Principle, SRP): Каждый класс должен иметь только одну причину для изменения.
  • O - Принцип открытости/закрытости (Open/Closed Principle, OCP): Программные сущности (классы, модули и т. д.) должны быть открыты для расширения, но закрыты для модификации.
  • L - Принцип подстановки Барбары Лисков (Liskov Substitution Principle, LSP): Объекты базового класса должны быть заменяемыми объектами производных классов без изменения корректности программы.
  • I - Принцип разделения интерфейса (Interface Segregation Principle, ISP): Клиенты не должны зависеть от интерфейсов, которые они не используют.
  • D - Принцип инверсии зависимостей (Dependency Inversion Principle, DIP): Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба должны зависеть от абстракций.

DRY (Don't Repeat Yourself):

Принцип DRY направлен на уменьшение повторения кода и информации. Каждая часть знания должна иметь единственное, однозначное, авторитетное представление в системе. Этот принцип призывает избегать дублирования кода в системе. Любой фрагмент информации или функциональности должен существовать в единственном экземпляре.

YAGNI (You Aren't Gonna Need It):

Принцип YAGNI предлагает не добавлять функциональность, пока она действительно не понадобится. Это помогает избежать ненужной сложности и потери времени на разработку функций, которые могут никогда не использоваться.

https://refactoring.guru/design-patterns

SOLID-принципы

Принципы для построения устойчивых и расширяемых систем:

  • S (Single Responsibility Principle) — у каждого модуля должна быть одна ответственность.
  • O (Open/Closed Principle) — модули должны быть открыты для расширения, но закрыты для модификации.
  • L (Liskov Substitution Principle) — наследники должны быть заменяемы базовым классом/интерфейсом.
  • I (Interface Segregation Principle) — интерфейсы должны быть небольшими и специфичными.
  • D (Dependency Inversion Principle) — модули должны зависеть от абстракций, а не от конкретных реализаций.

https://habr.com/ru/articles/348852/

Чистая архитектура (Clean Architecture)

Архитектурный подход, предложенный Робертом Мартином (Uncle Bob), для создания легко поддерживаемых и масштабируемых приложений.

Основные слои:

  • Entities — бизнес сущности, являются центральной частью приложения.
  • Use Cases — реализация логики приложений.
  • Interfaces/Adapters — адаптеры для внешних систем (БД, HTTP).
  • Frameworks & Drivers — инфраструктурный код (ORM, роутеры и т.д.).

https://habr.com/ru/companies/otus/articles/732178/

Domain-Driven Design (DDD)

DDD — это подход к разработке сложных программных систем на основе моделей предметной области.

https://habr.com/ru/articles/809831/