Хочется вспомнить SOLID принципы и рассмотреть, как можно их применять в разработке интерфейсов на примере React компонентов.
S: Single Responsibility Principle (Принцип единственной ответственности). Означает, что каждый класс/функция/компонент должны выполнять только одну конкретную задачу.
На примере React компонента: компонент, который отрисовывает пользовательский интерфейс, не должен содержать в себе логику авторизации этого пользователя.
O: Open-Closed Principle (Принцип открытости-закрытости). Означает, что класс/функция/компонент должны быть открыты для расширения, но закрыты для модификации. Чтобы их можно было расширять новым функционалом, не изменяя при этом исходный код.
На примере React компонента:
На примере выше мы имеем абстрактную базовую кнопку, которую мы не можем изменять, но можем расширять, за счет передачи таких значений как className
, onClick
и children
Еще один способ реализовать данный принцип в React – использовать HOC (читается не как нос, а как хок) (Higher-Order Component) — это функция, которая принимает компонент и возвращает новый компонент с добавленным поведением или функциональностью. Это отличный способ повторно использовать логику в разных компонентах.
L: LSP (Принцип подстановки Барбары Лисков). Это означает, что объекты базовых классов должны быть заменяемы объектами производных классов без изменения ожидаемого поведения программы. То есть производные классов должны мочь использоваться в тех местах, где используется базовый класс без каких-либо изменений
На примере React компонента:
В базовом классе Payment
мы определяем метод processPayment
, который будет обрабатывать платеж. Этот метод должен быть реализован в подклассах.
Оба подкласса (CreditCardPayment
и PayPalPayment
) реализуют метод processPayment
, каждый по-своему. Но оба класса сохраняют контракт, заданный базовым классом, и могут быть использованы взаимозаменяемо.
Функция processOrder
принимает объект paymentMethod
, который является экземпляром любого класса, наследующего Payment
, и вызывает метод processPayment
. Благодаря принципу подстановки Лисков, мы можем передавать как CreditCardPayment
, так и PayPalPayment
в функцию processOrder
, и она будет корректно обрабатывать любой тип платежа.
Тоже самое работает с примером с кнопками, каждый вид кнопки, который расширил базовую, может использоваться вместо базовой без каких-либо изменений, соответственно выполняется прицип LSP.
I: ISP (Принцип разделения интерфейса). Означает что классы/функции/компоненты не должны зависеть от интерфейсов, в которых они не нуждаются.
На примере React компонента: самое простое объяснение нарушения данного принципа — передавать в компонент огромный объект, а использовать только одно его поле.
В примере выше, стоит в компонент UserName
передавать только поле имени, а не весь объект
D: DIP (Принцип инверсии зависимостей). Означает что высокоуровневые модули не должны зависеть от низкоуровневых модулей
На примере React компонента: рассмотрим такой компонент
Мы имеем простой компонент с кнопкой, по нажатию на которую происходит логирование. В данном примере высокоуровневым компонентом у нас является кнопка, а низкоуровневым — функция логгер (ConsoleLogger
) ее нажатия. Как мы видим кнопка напрямую зависит от реализации данного логгера, а согласно принципу, она должна зависеть от абстракции. Проблема в том, что если придется использовать другой способ логирования, то придуется изменять код компонента
Посмотрим на компонент, соответствующий принципу DIP
Мы определили интерфейс функции логгера, создали несколько конкретных реализаций логгера, которые соответствуют определенному интерфейсу. Компонент UserService
теперь принимает логгер через пропс, что позволяет легко менять реализацию логгера, не изменяю при этом код компонента. Благодаря чему, мы можем использовать UserService
с любым логгером, который реализует интерфейс ILogger
Заключение
Таким образом, несмотря на то, что принципы SOLID были изначально разработаны и применялись для ООП разработки, оказывается, что их можно вполне успешно применять в функциональном программировании при разработке интерфейсов — круто
Если понравилось — подписывайтесь на канал в тг, буду писать интересное там
Автор: and-kushnir