Содержание
Принципы S.O.L.I.D в картинках с объяснениями
php
Fomenko Alexander
• 4 min read
Если вы знакомы с Объектно-ориентированным программированием, то вы, вероятно, слышали о принципах SOLID. Я ранее писал об этом статью, где рассматривал эти принципы с примерами кода. Эта статья, мне кажется, получилась отличным дополнением. Здесь, я, в простой, понятной манере, на картинках покажу, что есть SOLID и с чем его солят.
Эти пять принципов разработки программного обеспечения являются руководством, которому нужно следовать при создании программного обеспечения, чтобы его было легче масштабировать и поддерживать. Они были сделаны популярными инженером-программистом Робертом К. Мартином.
В Интернете так много замечательных статей о SOLID, но я редко вижу примеры с картинками. Научно доказано, что информация проще всего усваивается с помощью визуальной памяти. Так почему, нам не рассмотреть принципы S.O.L.I.D на картинках.
Поэтому основная цель этой статьи — лучше понять эти принципы, используя иллюстрации для подчеркивания ключевой цели для каждого принципа.
Понимаете, некоторые из этих принципов могут выглядеть похожими, но они не преследуют одну и ту же цель. Можно удовлетворить один принцип, нарушая другой, даже если они похожи.
Для простоты изложения я буду использовать слово «Класс», но обратите внимание, что в этой статье оно также может относиться и к функции, методу или модулю.
Принципы SOLID
S — Единая ответственность
Класс должен нести единственную ответственность
Если у класса много обязанностей, это увеличивает вероятность возникновения ошибок, потому что внесение изменений в одну из его обязанностей, может повлиять на другую без вашего ведома.
Цель
Этот принцип направлен на разделение поведения таким образом, чтобы в случае возникновения ошибок в результате ваших изменений, это не повлияло на другие, не связанные с этим обязанности.
O — Принцип открытости/закрытости
Классы должны быть открыты для расширения, но закрыты для модификации.
Изменение текущего поведения класса повлияет на все системы, использующие этот класс.
Если вы хотите, чтобы Класс выполнял больше функций, то идеальным подходом является добавление нового функционала к уже существующим функциям НЕ изменять существующие.
Цель
Этот принцип направлен на расширение поведения Класса без изменения существующего поведения этого Класса. Это сделано для того, чтобы избежать возникновения ошибок везде, где используется данный класс.
Л — Принцип подстановки Барбары Лисков
Если S является подтипом T, то объекты типа T в программе могут быть заменены объектами типа S без изменения каких-либо дополнительных свойств этой программы.
Когда дочерний класс не может выполнять те же действия, что и его родительский класс, это может привести к ошибкам.
Если вы имеете класс и создаете другой класс из него, он становится родителем, а новый класс становится дочерним. Дочерний класс должен быть в состоянии сделать все, что может сделать родительский класс. Этот процесс называется Наследованием.
Дочерний класс должен быть способен обрабатывать те же самые запросы и выдавать тот же самый результат, что и родительский класс, или он может выдать результат, который имеет тот же самый тип.
Рисунок показывает, что родительский класс приносит кофе (это может быть любой тип кофе). Для дочернего класса приемлемо приносить капучино, потому что это специфический тип кофе, но НЕ приемлемо доставлять воду.
Если дочерний класс не соответствует этим требованиям, это означает, что дочерний класс полностью изменяется и нарушает этот принцип.
Цель
Этот принцип направлен на обеспечение последовательности, чтобы родительский класс или его дочерний класс могли использоваться одинаковым образом, и были взаимозаменяемы, без каких-либо ошибок.
I — Сегрегация интерфейсов
Клиенты не должны зависеть от методов, которые они не используют.
Когда от Класса требуется выполнение действий, которые он не должен делать, или не может, это расточительно и может привести к неожиданным ошибкам. Очень часто бывает, что Класс не имеет возможности выполнить эти действия, хотя интерфейс обязует что-то с этим делать.
Класс должен выполнять только те действия, которые необходимы для выполнения его функции. Любое другое действие должно быть полностью удалено или перемещено куда-либо еще, если оно может быть использовано другим классом в будущем.
То есть, главный посыл в этом — разделение толстых интерфейсов, которые «делают всё», на более узконаправленные интерфейсы, решающие узконаправленную задачу.
Цель
Этот принцип направлен на разделение набора действий на более мелкие наборы таким образом, чтобы класс выполнял ТОЛЬКО тот набор действий, который ему нужен.
D — Принцип инверсии зависимостей
- Высокоуровневые модули не должны зависеть от более низкоуровневых модулей. Оба должны зависеть от абстракции.
- Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.
Во-первых, давайте определим термины, используемые здесь, проще.
Высокроуровневый Модуль(или класс): Класс, выполняющий действие с помощью инструмента.
Низкоуровневый модуль (или класс): Инструмент, необходимый для выполнения действия.
Абстракция: Представляет собой интерфейс, соединяющий два класса.
Детали: То, как работает инструмент.
Этот принцип гласит, что класс не должен смешиваться с инструментом, который он использует для выполнения действия. Скорее, он должен быть объединен с интерфейсом, который позволит инструменту соединиться с классом.
Он также говорит, что и класс, и интерфейс не должны знать, как работает инструмент. Однако, инструмент должен соответствовать спецификации интерфейса.
Цель
Этот принцип направлен на уменьшение зависимости высокоуровневого класса от низкоуровневого путем внедрения интерфейса.
До сих пор мы обсуждали эти пять принципов и подчеркивали их цели. Они призваны помочь вам сделать ваш код простым в настройке, расширении и тестировании без особых проблем.
Большое спасибо за чтение. Я надеюсь, что у вас появилось более полное представление об этой теме, и вам было так же весело читать ее, как и мне.
SOLID принципы часть 1 — Еще один блог веб-разработчика
Spread the love
В интернете можно найти много статей описывающий принципы SOLID. Но большинство из них сложны для понимая, а некоторые даже не содержать примеров кода, а те в которых есть примеры используют свойственные выбранному языку абстракции, такие как интерфейсы или абстрактные классы. Поэтому я постарался создать статью описывающие эти принципы простым языком и содержащие примеры не использующие особенности какого либо языка. Это статья создана на основе вот этой очень хорошей презентации и дополнена описанием и примерами.
И так в этой статье я расскажу про пять архитектурных принципов программирования, которые помогут сделать ваш код гибким, понятным и легко поддерживаемым. Все о чем будет рассказано далее находится в книги Роберт К. Мартин Гибкая разработка программ. Принципы, примеры, практика (Agile Software Development Principles, Patterns and Practices )
Что такое Solid принципы?
Solid – переводится с английского как твердый, крепкий прочный, но с другой стороны SOLID это акроним, где каждая буква этого слова это отдельный принцип:
S – Single Responsible Principle (SRP)
O – Open Closed Principle (OCP)
L – Liskov Substitution Principle (LSP)
I – Interface Segregation Principle (ISP)
D – Dependency Inversion Principle (DIP)
Каждый принцип сам по себе является целой идеологией и все они не зависят друг от друга. Но вместе они позволяют делать код более понимаемым, лучше описаным и поддерживаемым. Говоря о эти принципах, вначале нужно сказать, а почему вообще эти принципы так важны и для чего они вообще нужны и какой смысл, в том что бы их изучать и что такое плохой код.
Самая большая проблема в написание программ заключается в том что всегда происходят изменения. В реальной жизни почти никогда не бывает что бы вы один раз написали код и больше к нему не возвращались. Как правило всегда нужно вносить какие либо изменения, для добавление нового функционала, исправления старых ошибок и т.п. Поэтому нужно писать код так что бы эти изменения не создавали новых проблем, а процесс внесения изменений был естественной часть технологического процесса и вам приходилось бы тратить больше времени не на поддержку старого кода, а на написания нового.
В книги Роберта Мартина описано 7 признаков плохого кода:
- Закрепощенность Любое изменения вызывает эффект “снежного кома”
- Неустойчивость. Изменения ломают систему в коде не имеющем прямого отношения к изменяемому компоненту
- Неподвижность. Невозможность разделить код на компоненты и использовать в другом месте
- Вязкость.
Проще сломать систему, чем сделать в ней что то правильное
- Неоправданная сложность. Проект перенасыщен сложными конструкциями и решениями
- Неоправданные повторения. Наличия повторяющихся структур в коде, которые можно выделить в отдельные абстракции
- Неопределенность. Трудность чтения и понимание проекта
И так начнем описание принципов.
Принцип персональной ответственности (SRP Single Responsibility Principle)
Каноническое определение принципа:
“Существует лишь одна причина, приводящая к изменению класса”
Том Де-Марко (1979) и Мейлер Пейдж-Джонсан (1988)
То есть этот принцип говорит, что каждый класс должен иметь лишь одну ответственность, то есть он должен отвечать только за одну вещь.
Хотя концепция, лежащая в основе SRP, достаточно проста для понимания, но реализация этого принципа на практике требует определенных навыков, поскольку ответственность класса не всегда сразу очевидна.
Мартин рассматривает ответственность как причину изменения и приходит к выводу, что у класса и модуля должна быть единственная причина для изменения. Объединение двух сущностей, которые меняются по разным причинам в разное время, – является плохим дизайном. Чем больше обязанностей у класса, тем больше запросов на изменение он получит, и тем сложнее будет реализовать эти изменения. Цель принципа SRP – бороться со сложностью, которая возникает в процессе разработки логики приложения.
Рассмотрим пример. Пусть у нас есть один класс Product, в котором определены все необходимые методы для работы с сущностью продукта, с базой и методы отображения продукта.
class Product { function get(name) {} function set(name, value) {} function save() {} function update() {} function delete() {} function show() {} function print() {} }
В данном случае мы явно нарушаем принцип так как наш класс содержит множество ответственностей. Перепишем его, так что бы выделить методы в отдельные классы.
class ProductEntity { function get(name) {} function set(name, value) {} } class ProductRepository { function save() {} function update() {} function delete() {} } class ProductView { function show() {} function print() {} }
Как мы можем видеть код стал намного более понятным.
Рассмотрим еще один пример, класс User:
// сохранение данных user = new User() user.firstname = 'James' user.lastname = 'Bond' user.save() // получение данных из базы user2 = new User() user2.getByFirstName('John') // получение данных их связанной таблицы role = user2.role
При такой архитектуре все будет хорошо работать если проект будет небольшим. Но с ростом проекта увеличением количества требуемых методов, будет расти и сложность архитектуры, все очень быстро может стать запутанным, поэтому лучше это переделать. Разделить на сущность пользователя класс UserEntity и класс для работы с базой данных UserRepository
// сохранение данных user = new UserEntity() user.firstname = 'James' user.lastname = 'Bond' userRepository = new UserRepository() userRepository.save(user) // получение данных userRepository2 = new UserRepository() userRepository2.getByFirstName('John') // получение данных их связанной таблицы role = userRepository2.role
Еще один пример. Пусть у нас есть класс, который отвечает как за генерацию отчета и за его отправку определенному пользователю
class FinancialReportMailer function FinancialReportMailer(transactions, account) this.transactions = transactions this.account = account this.report = '' function generate_report() // generate report this.report = make_report function send_report() // send report this.report mailer = FinancialReportMailer(transactions, account) mailer.generate_report() mailer.send_report()
Класс FinancialReportMailer, показанный выше, выполняет две задачи: генерация отчета (метод «generate_report!») И отправка отчета (метод «send_report»). Класс выглядит довольно простым. Однако расширение этого класса в будущем может быть проблематичным, поскольку нам, вероятно, придется изменить логику класса. Принцип SRP говорит нам, что класс должен реализовывать одну единственную задачу, и поэтому в соответствии с этим принципом мы должны разделить класс FinancialReportMailer на два класса.
Давайте посмотрим, как выглядит этот код после того, как мы реорганизовали его для соответствия требованиям SRP:
class FinancialReportMailer function deliver(report, account) // send report class FinancialReportGenerator function generate() // generate report report = FinancialReportGenerator().generate() FinancialReportMailer.deliver(report, account)
После рефакторинга у нас есть два класса, каждый из которых выполняет определенную задачу. Класс FinancialReportMailer отправляет электронные письма, содержащие тексты, созданные классом FinancialReportGenerator. Если бы мы хотели расширить класс, отвечающий за генерацию отчетов в будущем, мы могли бы просто внести необходимые изменения, не касаясь класса FinancialReportMailer.
Этот принцип применяется, когда:
- Нужно сделать код гибким и легко изменяемым.
- Сложно заранее определить вектор изменений.
- Разделение функционала – долгая и сложная операция, нежели его объединение, поэтому отдавайте предпочтение декомпозиции. То есть старайтесь сразу создать архитектуру из небольших, независимых друг от друга сущностей.
Не используйте этот принцип когда:
- Заранее известно о неизменяемости кода в конкретном месте
- Решение сильно усложняет разработку и поддержку кода.
Всегда нужно сохранять баланс между количеством классов и их необходимостью.
Пример когда следовать этому принципу не нужно.
Допустим нам нужно написать класс Modem, о котором мы точно знаем что в будущем мы не будем вносить в него изменения.
class Modem { function dial(){} function hangup() {} function send(request) {} function receive() {} }
Если мы будем придерживаться принципа SRP, то нам нужно будет разделить этот класс на два класса DataChannel для организации соединения и Connection для передачи данных.
class DataChannel { function dial(){} function hangup() {} } class Connection { function send(request) {} function receive() {} }
Но так как мы заранее знаем, что мы никогда не будем менять класс Modem, то в данном случае все таки выгоднее оставить все как есть, иначе в будущем наш код будет иметь избыточную сложность
Суть принципа
На каждый объект должна быть возложена одна единственная обязанность
Принцип открытости / закрытости (OCP Open Closed Principle)
Каноническое определение принципа:
Программные объекты (классы, модули, функции и т.
п.) должны быть открыты для расширения, но в то же время закрыты для модификации.
Бертран Майер (1988)
Как что-то может быть открытым и закрытым одновременно?!
Класс следует OCP, если он удовлетворяет этим двум критериям:
Открыт для расширения
То есть класс должен быть создан таким образом, что бы поведение класса можно было бы дополнить в любой момент. По мере изменения требований мы должны иметь возможность дополнить класс новым функционалом.
Закрыт для модификации
При добавление нового функционала нельзя вносить изменения в исходный код такого класса. То есть весь новый код не должен затрагивать старый.
Цель принципа
Разработчики всегда должны писать новый код, а не переписывает старый. Тестирование кода должно происходит единожды. И разработчики не должны тратить время на частый рефакторинг
Рассмотрим простой пример. Пусть у нас есть класс Order и метод getTotalPrice, которые вначале получает все позиции корзины потом получает возможные скидки, а потом рассчитывает итоговую сумму.
class Order { function getTotalPrice() { // получение всех позиций корзины // получение накопительности скидки текущего клиента // расчет итоговой цены } }
В начале перепишем его, так что бы он удовлетворял принципу единой обязанности SIP
class BaseOrderAlgorithm { function getTotalPrice() { products = this.getProducts() discount = this.getDiscount() return this.calculate(products, discount) } function getProducts() {} function getDiscount() {} function calculate(products, discount) {} }
Далее перепишем его так что бы он удовлетворил принципу OCP. У нас будет два возможных решения. Первой очень простое, второе чуть интереснее.
Первое решение для соответствия принципу OCP. Мы можем просто унаследовать дочерний класс MainOrderAlgorithm от BaseOrderAlgorithm и переопределить внутренние методы расчета getProducts и getDiscount. Таким образом мы сохраним старый код и добавим новый.
class MainOrderAlgorithm extends(BaseOrderAlgorithm) { function getProducts() {} function getDiscount() {} }
Второе решение для соответствия принципу OCP.
class Order { function Order(IProduct product, IDiscount discount) { this.product = product this.discount = discount } function getTotalPrice() { products = this.product.getProducts() discount = this.discount.getDiscount() return this.calculate(products, discount) } function calculate(products, discount) {} }
Через конструктор класса передаем отдельные классы product и discount И таким образом мы написали один раз класс Order и можем написать множество классов для обработки.
Применяйте принцип в местах подтвержденных частым изменениям.
Так же наличие условных операторов (if, case) при ветвление бизнес логики может сигнализировать о потенциальных точках изменения логики.
Возможная проблемы с принципом OCP
Пусть у нас есть некая фабрика которая на основе неких параметров создает новый класс
switch (name) { case 'Shape': return new Shape() case 'Rectangle': return new Rectangle() }
Тут проблема в том что когда вам надо добавить новую фигуру вам каждый раз надо будет вставлять/редактировать текущий код то есть каждый раз переписывать этот класс.
Возможное решение
Полностью избавиться от подобных классов/методов почти невозможно поэтому:
- Изолируйте такой код в классы фабрики
- В таких ситуациях используйте внедрение зависимостей
- Старайтесь зависеть от интерфейсов и абстракций а не от от конкретных классов (более подробно об этом позже)
Максимальное использование абстракций может показаться идеальным способом приведения любых классов в соответствие с принципом OCP. Но тут есть определенные проблемы о которых заранее лучше знать:
- На придумывания абстракций может уходить много времени.
- Неудачные абстракции засоряют код и усложняют рефакторинг.
- Повсеместное применени абстракций увеличивает сложность понимания и сопровождение проекта
- Сложно придумывать код так что бы при любых изменениях требований исходный код не менялся. Так же следует учесть что невозможно придумать такую абстракцию которая удовлетворит всему спектру возможных изменений.
Только большой опыт разработки позволит делать точные предположение, о том как следует делать код не изменяемым.
Пример с большим количеством if/case:
В приведенном ниже коде класс Logger форматирует и отправляет журналы логов. Но принцип OCP не соблюдается, поскольку нам придется изменять регистратор каждый раз, когда нам нужно добавить дополнительных типы отправлений или типы форматов:
class Logger function Logger(format, delivery) this.log(this.format(format), this.delivery(delivery)) function log(string) this.deliver(this.format(string)) function format(string): case: string == raw: // краткий формат string == with_date: // формат с датами string == with_date_and_details: // детализированный формат с датами else raise NotImplementedError function deliver(text): case: text == by_email: // отправка по почте text == by_sms: // отправка по смс text == to_stdout: // вывод в консоль else raise NotImplementedError logger = Logger('raw', 'by_sms') logger.log('Emergency error! Please fix me!')
После того, как мы проведем рефакторинг этого кода, он может быть расширен. В приведенном ниже примере мы создали отдельные классы для отправителей и для форматирования и сделали возможным подключение новых отправителей и средств форматирования без необходимости изменения базового кода:
class Logger function Logger(formatter, sender) this.formatter = formatter this.sender = sender function log(string) this.sender.deliver(this.formatter.format(string)) class LogSms function deliver(text): // отправка по СМС class LogMailer function deliver(text): // отправка по почте class LogWriter function deliver(log) // вывод в консоль class DateFormatter function format(string) // формат с датой class DateDetailsFormatter function format(string) // детализированный формат class RawFormatter def format(string) // краткая форма формата logger = Logger.new(RawFormatter(), LogSms()) logger.log('Emergency error! Please fix me!')
Суть принципа
Изменения в программе должны происходить при написание нового кода, а не модификации старого.
Далее в следующей статье я продолжу описание принципов.
Была ли вам полезна эта статья?
[18 / 4.3]
Spread the love
Примеры SolidJS — React.js
SolidJS
Программы
Машинопись
Крючки
Nextjs
интерфейс
Веб-сайт
Игры
Попутный ветер CSS
Javascript
Редукс
Изображений
Стартер
Состояние
Делать
API
редактор
Разнообразный
Шаблоны
Анимация
Шаблон
Электронная торговля
Диаграмма
Инструмент
Форма
Реагировать на родной
Календарь
Firebase
Реагировать
Генератор
Страница портфолио
Маршрутизатор
Чат
Прокрутить
Стол
Инструмент разработчика
децентрализованное приложение
видео
Аутентификация
Вход
Панель приборов
Эфириум
Поиск
Блокчейн
MongoDB
Текст
Макет
SVG
МЕРН
Реализация игры Wordle на SolidJS
16 февраля 2023 г.
Расширение Chrome для создания тестов для solidjs
07 октября 2022 г.
Крошечный и производительный компонент свертывания для SolidJS
18 августа 2022 г.
Монорепозиторий для демонстрации архитектуры микроинтерфейса между двумя разными библиотеками (React, SolidJs)
15 августа 2022 г.
Конструктивная твердотельная геометрия для React
21 июля 2022 г.
Маршрутизатор браузера Solid.js, похожий на React, с простым вложением/динамическими маршрутами
30 июня 2022 г.
Библиотека Solidjs для работы с формами
07 июня 2022 г.
Библиотека компонентов hCaptcha для Solid.
27 мая 2022 г.
Настраиваемые всплывающие уведомления для SolidJS
26 мая 2022 г.
Средство визуализации форматированного текста с содержанием для Solid-JS, основанное на средстве визуализации Rich-Text-React-Renderer, но с некоторыми изменениями
21 мая 2022 г.
Шаблон для простого создания библиотеки ReactJS с помощью TypeScript
03 мая 2022 г.
Конвертер ReactJS в SolidJS, также известный как Transpiler
10 апреля 2022 г.
Плагин для Preview.js, добавляющий поддержку предварительного просмотра компонентов SolidJS
07 апреля 2022 г.
Утилита для отслеживания границ html-элементов в SolidJS
05 апреля 2022 г.
Простой шаблон интеграции Vite, SolidJS, Electron
19февраль 2022 г.
Обертка над Motion One, библиотекой анимации, созданной на основе API веб-анимации для наименьшего размера файла и максимальной производительности
11 февраля 2022 г.
Вводное децентрализованное приложение Эфириума с полным стеком, использующее: Solidity, Hardhat, react.js, ethers.js
22 января 2022 г.
Solidjs-lazily — простая оболочка над lazy SolidJS, поддерживающая именованный импорт
03 января 2022 г.
Полная реализация компонентов Bootstrap с использованием SolidJS
26 ноября 2021 г.
Рендеринг Markdown как твердые компоненты
11 октября 2021 г.
Полнофункциональная реализация перетаскивания для Solid JS с использованием пользовательской директивы
06 октября 2021 г.
Простые реактивные метки для SolidJS.
23 сентября 2021 г.
Принципы SOLID с примерами Node.js
Перейти к основному содержанию
Нитин Кадам
Нитин Кадам
Полный стек разработчиков | Лазурь | Node.
js | С# | .NET | SQL | Космос | JavaScript | Реагировать | GraphQL | Страсть к предоставлению исключительных решений для удовлетворения потребностей бизнеса.
Опубликовано 5 марта 2023 г.
+ Подписаться
Принципы SOLID — это набор рекомендаций по проектированию объектно-ориентированного программного обеспечения, цель которых — сделать код более удобным для сопровождения, повторного использования и масштабируемым. В этой статье мы рассмотрим пять принципов SOLID и то, как их можно применить к приложениям Node.js.
Принцип единой ответственности (SRP) SRP гласит, что у класса или модуля должна быть только одна причина для изменения. Другими словами, каждый класс или модуль должен иметь одну обязанность или задание. Это делает код более удобным для сопровождения и легче тестировать.
В приложении Node.js этот принцип можно применить, разбив функциональность на более мелкие, более специализированные модули. Например, вместо создания большого монолитного файла, который обрабатывает как аутентификацию, так и операции с базой данных, разделите эти задачи на отдельные модули.
Принцип открытости/закрытости (OCP) OCP утверждает, что класс или модуль должен быть открыт для расширения, но закрыт для модификации. Другими словами, вы должны иметь возможность расширять поведение класса или модуля без изменения исходного кода. Это делает код более масштабируемым и простым в обслуживании.
В приложении Node.js этот принцип можно применить, используя интерфейсы или абстрактные классы для определения поведения модуля. Например, вместо прямого доступа к базе данных в модуле создайте интерфейс для операций с базой данных и внедрите конкретную реализацию базы данных во время выполнения.
Принцип замещения Лискова (LSP) LSP утверждает, что производный класс или модуль должен иметь возможность использоваться вместо родительского класса или модуля без ущерба для правильности программы. Другими словами, производный класс должен вести себя так же, как его родительский класс.
В приложении Node.js этот принцип можно применить, гарантируя, что производные классы или модули реализуют тот же интерфейс или абстрактный класс, что и их родитель. Например, если у вас есть модуль регистратора, который записывает сообщения в файл, производный модуль регистратора, записывающий сообщения в базу данных, должен реализовывать тот же интерфейс, что и родительский модуль регистратора.
Принцип разделения интерфейсов (ISP) ISP заявляет, что клиенты не должны зависеть от интерфейсов, которые они не используют. Другими словами, вы должны создавать небольшие специализированные интерфейсы, которые содержат только те методы или свойства, которые нужны клиенту.
В приложении Node.js этот принцип можно применить, разбив большие интерфейсы на более мелкие, более целенаправленные. Например, вместо создания большого интерфейса, определяющего все операции с базой данных, создайте меньшие интерфейсы для определенных операций с базой данных, таких как «вставка», «обновление» и «удаление».
Принцип инверсии зависимостей (DIP) DIP гласит, что модули высокого уровня не должны зависеть от модулей низкого уровня. Вместо этого оба должны зависеть от абстракций. Другими словами, модули должны зависеть от абстракций, а не от конкретных реализаций.
В приложении Node.js этот принцип можно применить, используя внедрение зависимостей для внедрения зависимостей во время выполнения. Например, вместо создания подключения к базе данных в модуле внедрите подключение к базе данных во время выполнения, используя инфраструктуру внедрения зависимостей, такую как InversifyJS.
Заключение Применяя принципы SOLID к своим приложениям Node.js, вы можете создавать более удобный в сопровождении, многократно используемый и масштабируемый код. Эти принципы могут помочь вам разбить функциональность на более мелкие, более целенаправленные модули, создать масштабируемые интерфейсы и внедрить зависимости во время выполнения. Имея в своем распоряжении эти инструменты, вы можете создавать приложения Node. js, которые проще разрабатывать, поддерживать и расширять.
… ПРОДОЛЖЕНИЕ СЛЕДУЕТ
Оптимизация администрирования страховых полисов с помощью настраиваемой и гибкой системы
13 апр. 2023 г.
Манипуляции с массивами ES6 —
18 марта 2023 г.
5. Принцип инверсии зависимостей (DIP)
16 марта 2023 г.
4.
Принцип разделения интерфейсов (ISP)
16 марта 2023 г.
3. Принцип замещения Лисков (LSP)
16 марта 2023 г.
Teams MeetingBot с Node JS
10 марта 2023 г.
Микросервисы: революционный подход к созданию и развертыванию приложений
9 марта 2023 г.