Мир разработки программного обеспечения полон принципов, методологий и лучших практик, которые могут помочь разработчикам создавать высококачественное, удобное в сопровождении программное обеспечение. Среди этих принципов SOLID выделяется как широко принятый подход, направленный на то, чтобы сделать дизайн программного обеспечения более понятным, гибким и удобным в сопровождении. В этой статье мы углубимся во второй принцип SOLID: принцип открытости/закрытости (OCP).

Что такое принцип открытого/закрытого?

Принцип открытости/закрытости, термин, введенный Бертраном Мейером, гласит, что «объекты программного обеспечения (классы, модули, функции и т. д.) должны быть открыты для расширения, но закрыты для модификации». Этот принцип играет решающую роль, помогая нам контролировать сложность наших систем по мере их роста и изменения с течением времени.

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

Принцип открытости/закрытости в мобильной разработке

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

Давайте рассмотрим пример на Swift, популярном языке разработки приложений для iOS. Рассмотрим приложение с классом DiscountCalculator, которое вычисляет скидки для различных типов продуктов.

class DiscountCalculator {
    func calculateDiscount(product: Product) -> Double {
        if product.type == .electronic {
            return product.price * 0.10
        } else if product.type == .fashion {
            return product.price * 0.20
        } 
        // other types...
        else {
            return 0.0
        }
    }
}

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

Теперь давайте рефакторим это, чтобы придерживаться OCP:

protocol Discountable {
    func calculateDiscount() -> Double
}
class ElectronicProduct: Discountable {
    var price: Double
    init(price: Double) {
        self.price = price
    }
    func calculateDiscount() -> Double {
        return price * 0.10
    }
}
class FashionProduct: Discountable {
    var price: Double
    init(price: Double) {
        self.price = price
    }
    func calculateDiscount() -> Double {
        return price * 0.20
    }
}

И тогда мы можем упростить наш класс DiscountCalculator:

class DiscountCalculator {
    func calculateDiscount(product: Discountable) -> Double {
        return product.calculateDiscount()
    }
}

Теперь DiscountCalculator закрыт для модификации, но открыт для расширения. Если мы хотим добавить новый тип продукта, нам просто нужно создать новый класс, соответствующий протоколу Discountable. Такой подход снижает риск внесения новых ошибок в существующий код.

Практический пример: приложение для электронной коммерции

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

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

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

Заключение

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

Помните, что цель этих принципов не в том, чтобы применить их догматически, а в том, чтобы понять их и использовать там, где они имеют смысл и приносят пользу. Удачного кодирования!