Контекст и парадигмы программирования

в 6:15, , рубрики: .net, .net8, python, контекст, ооп, ООП программирование, сложность

Разработка программного обеспечения — это не только процесс создания кода, но и его сопровождение. Чем сложнее код, тем дороже его поддержка, выше вероятность ошибок и дольше адаптация новых разработчиков. Один из ключевых факторов, влияющих на сложность кода, — это именования и контекст, который они несут. Помимо этого, выбранная парадигма программирования также влияет на читаемость и понятность кода. В этой статье я хотел показать, как правильно выбирать имена, как контекст упрощает понимание и какие различия в управлении сложностью между функциональным и объектно-ориентированным стилями программирования.

Контекст это все и для ИИ и для человека!

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

Плохой вариант:

var d = DateTime.Now.AddDays(2);

Хороший вариант:

var deliveryDate = DateTime.Now.AddDays(2);

Давайте поговорим о контексте. Что же такое контекст? Контекст — это та логическая область, к которой мы соотносим какую-либо логическую единицу информации, например класс, сущность, переменную и т.д. В ООП языках примером является пространство имен, либо пакет, либо модуль.

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

Хороший вариант:

class Person
{
    public int Id { get; set; }
    public string FirstName { get; set; }
}

Плохой вариант:

class Person
{
    public int PersonId { get; set; }
    public string PersonFirstName { get; set; }
}

Первый вариант лучше, потому что в нем не дублируется контекст в названиях свойств.

Но если контекста нет, важно придерживаться обратного. Например, если в коде встречается переменная count, то без контекста неясно, что именно она считает. Если же назвать переменную activeUsersCount, смысл становится очевидным.

Принципы хорошего именования:

  • Использовать понятные, описательные имена.

  • Избегать сокращений, кроме общепринятых (id, url и т. д.).

  • Включать контекст прямо в название переменной или метода.

Объектно-ориентированный vs функциональный подход

Разные парадигмы программирования решают проблему сложности по-разному. Рассмотрим, как объектно-ориентированное и функциональное программирование влияют на читаемость и поддержку кода.

Объектно-ориентированный стиль

ООП структурирует код вокруг объектов и их поведения. Пример на C# с инкапсуляцией:

class Order
{
    public DateTime DeliveryDate { get; private set; }
    
    public Order(DateTime deliveryDate)
    {
        DeliveryDate = deliveryDate;
    }
}

Здесь вся информация об объекте заказа инкапсулирована в одном месте, что делает код более структурированным.

Наследование и полиморфизм

class Animal
{
    public virtual void Speak()
    {
        Console.WriteLine("Some sound");
    }
}

class Dog : Animal
{
    public override void Speak()
    {
        Console.WriteLine("Woof");
    }
}

class Cat : Animal
{
    public override void Speak()
    {
        Console.WriteLine("Meow");
    }
}

Использование полиморфизма:

List animals = new List { new Dog(), new Cat() };
foreach (var animal in animals)
{
    animal.Speak(); // Выведет "Woof" и "Meow"
}

Функциональный стиль

Функциональное программирование строится на чистых функциях и неизменяемых данных. Пример на Python с инкапсуляцией:

from datetime import datetime, timedelta

class Order:
    def __init__(self, delivery_date: datetime):
        self._delivery_date = delivery_date  # Инкапсуляция
    
    def get_delivery_date(self):
        return self._delivery_date

order = Order(datetime.now() + timedelta(days=2))
print(order.get_delivery_date())

Наследование и полиморфизм в функциональном стиле

Вместо классов можно использовать функции и замыкания:

def make_animal_speak(sound):
    def speak():
        print(sound)
    return speak

Dog = make_animal_speak("Woof")
Cat = make_animal_speak("Meow")

animals = [Dog, Cat]
for animal in animals:
    animal()  # Выведет "Woof" и "Meow"

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

Когда использовать ООП, а когда функциональный стиль?

  • ООП удобно для моделирования сложных предметных областей с четкой иерархией сущностей.

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

  • В реальных проектах чаще всего используется смесь обоих подходов.

Заключение

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

P.S.: это моя первая статья здесь, я буду стараться ее улучшать. Я поделился своим опытом как бороться со сложностью на больших проектах. Если интересно я могу написать еще больше методик.

Автор: S1908

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js