Давайте начнем с основ ООП (объектно-ориентированного программирования), прежде чем перейти к принципам S.O.L.I.D. Абстракция, инкапсуляция, наследование и полиморфизм — вот четыре основных аспекта. В результате принципы S.O.L.I.D применяются к концепциям ООП. ТВЕРДЫЙ. — популярный набор принципов проектирования, используемых при разработке объектно-ориентированного программного обеспечения. S.O.L.I.D — это мнемоническая аббревиатура пяти принципов проектирования, используемых в разработке программного обеспечения: принцип единой ответственности, принцип открытости-закрытости, замена Лискова, разделение интерфейса и инверсия зависимостей. Эти принципы призваны сделать дизайн программного обеспечения более понятным, гибким и удобным в сопровождении. Их популяризировал инженер-программист Роберт С. Мартин. Рассмотрим подробнее каждый принцип.
Принцип единой ответственности
«У класса должна быть одна и только одна причина для изменения, а это означает, что у класса должна быть только одна работа»
Говорим ли мы о классе, пакете, компоненте или приложении, все они должны быть сосредоточены на достижении одной цели за раз. Это означает, что класс выполнит только одно задание. Например, если у вас есть класс, который мы часто меняем по разным причинам, вы должны разделить его на несколько классов, каждый из которых имеет определенную цель. Если после этого возникнет ошибка, ее, несомненно, будет легче найти и исправить. Кроме того, вы заметите увеличение количества повторного использования.
Принцип Открытости/Закрытости (OCP)
«Объекты или сущности должны быть открыты для расширения, но закрыты для модификации»
Это означает, что мы должны писать код таким образом, чтобы можно было добавлять новые функции, не изменяя существующий код.
Симптом нарушения ОСР
✍️Влияет на стабильность кода
›Причина нестабильности кода
›Повторное тестирование, повторное развертывание требуют затрат и времени
Мы меняем существующий код настолько, что он станет нестабильным.
✍️Сложность кода
›Код становится неуправляемым.
Принцип замены Лисков
«Каждый подкласс/производный класс должен иметь возможность заменить родительский/базовый класс»
Если вы пишете функцию или класс, который использует параметр или переменную некоторого базового класса, вы должны иметь возможность передавать экземпляр некоторого класса-потомка, и поведение должно оставаться точно таким же.
✍️Преимущества принципа замещения Лискова
· Способствует повторному использованию кода
· Расширить свои базовые классы без их поведения
✍️Ограничения на использование
· При расширении класса он должен выполнять основные функции базового класса.
· Дочерний класс не должен иметь нереализованных методов.
· Дочерний класс не должен придавать другое значение методам, существующим в базовом классе, после их переопределения.
Принцип разделения интерфейсов
«Клиентов нельзя заставлять внедрять методы, которые они не используют»
Мы не можем применить метод «летать» к классу автомобиля. Однако метод fly должен быть включен как в родительский класс Vehicle, так и в класс Aircraft. Толстые интерфейсы — вот как они называются. Методы должны быть разделены на несколько интерфейсов, каждый из которых обслуживает свою группу клиентов.
Решение
В качестве обходного пути нам придется создать новый класс и добавить к нему метод fly. Чтобы добавить метод fly, я использую класс flyable, как показано в примере. Класс самолета может наследоваться от класса flyable и реализовывать функциональные возможности, в то время как класс автомобиля может наследоваться от родительского класса Vehicle и реализовывать дополнительные функциональные возможности. Таким образом, это оптимальное решение проблемы принципа разделения интерфейсов.
Принцип инверсии зависимостей
«Модули более высокого уровня не должны зависеть от модулей более низкого уровня, но они должны зависеть от абстракций»
Пример-
Вот три класса, названные Project (высокий уровень), BackEndDeveloper (нижний уровень) и FrontEndDeveloper (нижний уровень).
Согласно примеру, класс проекта имеет 2 объекта с именами BackEndDeveloper и FrontEndDeveloper, которые являются низкоуровневыми моделями непосредственно в нем. В этом подходе нарушается принцип инверсии зависимостей. Вы ясно видите, что в моделях более низкого уровня они напрямую зависят от детализации метода.
поэтому мы можем видеть, что этот пример нарушил оба ограничения в принципе инверсии зависимостей.
Решение
Чтобы избавиться от этой проблемы, мы должны создать новый интерфейс. Это может быть интерфейс или абстрактный класс.
Я создал интерфейс с именем Developer и реализовал метод develop().
Затем после этого этот метод разработчика также должен быть реализован в модулях более низкого уровня. (FrontEndDeveloper и BackEndDeveloper) Внутри метода разработчика мы можем добавить методы записи отдельно.
Так
Теперь класс нижнего уровня не зависит напрямую от детализации метода. Наконец, мы должны исправить класс более высокого уровня Project.
Внутри проекта класс удаляем те объекты, которые были ранее и реализуем метод разработчика, который мы создаем в интерфейсе разработчика.
Таким образом, мы достигаем и 2-го ограничения в принципе инверсии зависимостей.
Подход к решению
«В разработке программного обеспечения мы пытаемся найти техническое решение бизнес-проблемы».
Как мы можем достичь этого решения наилучшим образом?
✍️ Продумайте всю проблему
› Прежде всего, обдумайте проблему, прежде чем найти решение или даже начать думать о нем. Затем убедитесь, что вы правильно понимаете проблему, которую собираетесь решить.
›Перед созданием решения убедитесь, что разъяснены все непонятные части. Странных вопросов нет, так что не пугайтесь их.
✍️Разделяй и властвуй
›Теперь разделите задачу на более мелкие задачи.
›Сделайте его управляемым и понятным.
›Постарайтесь найти идеальный баланс между приоритетом и четкостью
✍️ ПОЦЕЛУЙ
› Будь проще и глупее.
›Не усложняйте решение намеренно.
›Не переусердствуйте и не переусердствуйте.
✍️Учитесь, особенно на ошибках
›Примите перемены.
›Всегда предвосхищайте изменения, насколько это возможно.
›Не переусердствуйте, но сохраните положения для расширения
✍️ Всегда помните, зачем существует программное обеспечение
›Имейте в виду более широкую картину того, почему существует это программное обеспечение.
›Потеря общей картины может привести к неправильному пути.
✍️ Помните, что вы не пользователь
Внедрение решения
При внедрении разработанного решения необходимо помнить о некоторых рекомендациях.
✍️ YAGNI — Вам это не понадобится
›Напишите только тот код, который вам нужен на данный момент.
✍️ СУХОЙ — не повторяйтесь
› Пишите как можно лучше, сохраняйте его обобщенным и пригодным для повторного использования.
✍️ Примите абстракцию
›Убедитесь, что ваша система работает правильно, не зная деталей реализации каждого компонента.
✍️ DRITW — не изобретайте велосипед
›Возможно, кто-то уже решил ту же проблему. Используйте это.
✍️ Пишите код, который хорошо справляется с одной задачей
›Единый фрагмент кода, который делает одну и ту же вещь очень хорошо.
›Не пытайтесь написать волшебный код, который все сделает….
✍️ Отладка сложнее, чем написание кода
›Сделайте его как можно более читабельным.
›Читаемый код лучше компактного.
✍️ Кайдзен — оставьте лучше, чем когда вы его нашли
Практики
Практики — это нормы или наборы рекомендаций, которым мы должны следовать при разработке кода.
✍️Юнит-тестирование
Небольшой код, который проверяет части вашего основного кода. Модуль может быть классом, функцией, модулем, API и т. д. Модульный тест проверит класс, функцию. Работает, как ожидалось, и обеспечивает ожидаемый результат. Позволяет разработчику свободно изменять или улучшать код, чтобы убедиться, что он ничего не сломал, запустив модульный тест.
✍️Качество кода
Код должен быть легко читаемым и понятным. Код должен соответствовать передовым инженерным практикам, а также лучшим практикам языка и предметной области. Чаще анализируйте качество кода с помощью инструментов.
✍️Проверка кода
Проверка кода — лучший способ улучшить качество кода. Это цель — улучшить код, а не критиковать разработчика.
Экспертные проверки, обзоры лидов и парное программирование — вот некоторые методы проверки кода.
✍️Контроль версий
Git — самая известная система контроля версий.
✍️Постоянная интеграция
›Непрерывная интеграция — это практика разработки.
›Разработчикам необходимо возвращать код в общий репозиторий несколько раз в день.
›Каждая проверка проверяется автоматизированной сборкой.
›Это позволяет разработчикам обнаруживать проблемы на ранней стадии и устранять их без промедления.
JavaScript
https://en.wikipedia.org/wiki/JavaScript
Давайте посмотрим на характеристики JavaScript.
✍️По умолчанию программы JavaScript запускаются с использованием одного потока. Хотя есть способы создавать новые потоки, JavaScript считается однопоточным языком.
✍️JavaScript не ждет завершения операций ввода-вывода, а продолжает выполнение программы. Это называется неблокирующим вводом-выводом.
✍️JavaScript является асинхронным из-за природы NIO.
✍️JavaScript — это интерпретируемый язык программирования.
✍️Браузеры предоставляют интерпретаторы. Каждый браузер имеет свой собственный интерпретатор для выполнения JavaScript.
✍️JavaScript — это клиентский скрипт, используемый в веб-разработке для обработки взаимодействия и проверки на стороне клиента.
✍️JS имеет проблемы с совместимостью с браузером, так как каждый браузер имеет свой собственный javascript.
✍️Теперь мы видим javascript BOM (объектная модель браузера) и DOM (объектная модель документа).
✍️JavaScript поддерживает ООП, а также функциональное программирование (мультипарадигма).
Теперь давайте рассмотрим основы JavaScript
Классы и объекты
Теперь мы видим, что такое класс и объект,
✍️В JavaScript функция конструктора используется с ключевым словом «new» при создании объекта.
✍️Конструктор — это просто еще одна функция.
✍️Когда функция используется с ключевым словом «новое», эта функция действует как класс.
✍️Недавно в JavaScript появилось ключевое слово «класс», но оно еще не принято всеми движками JavaScript.
✍️Другой способ создания объекта — использование литералов объектов («{}»). Эти объекты считаются синглтонами.
✍️JavaScript поддерживает статические методы и переменные.
✍️Когда используется ключевое слово «новое», создается новый объект, и ему присваивается значение «этот» на время вызова функции конструктора.
Прототипы
Функции JavaScript имеют ссылку на другой объект, называемый прототипом. Это чем-то похоже на определение класса в других языках.
В JavaScript объект-прототип используется при создании объектов, для наследования и добавления методов в класс JavaScript.
›Это действительно другой экземпляр объекта.
Рассмотрим конструктор Person в приведенном выше примере.
Здесь функция прототипа теперь пуста {..}
›Из-за гибкости JavaScript существует несколько способов создания классов, а также их расширения. Прототипы являются рекомендуемым способом сделать это.
Ключевое слово extends используется для наследования функций и методов.
› Прототип функций используется для наследования свойств экземплярам объекта.
›Функция, которая используется для создания объектов, называется функцией-конструктором.
В качестве примера,
Этот код также использовал наследование прототипов JavaScript и функцию конструктора.
›Экземпляр объекта также имеет прототип. По сути, это экземпляр объекта, из которого создается объект. Объект «__proto__» — это место, где объект получает свои свойства, унаследованные от него.
это в JavaScript
Маловероятно, что в других языках JavaScript ключевое слово this действует иначе.
Внутри объекта «это» относится к самому объекту.
В глобальном контексте this относится к глобальному объекту (в браузере это объект окна). Это поведение будет изменено в строгом режиме.
Если функция, использующая ключевое слово this, передается другому объекту, то this будет ссылаться на этот объект, но не на исходный объект, в котором функция была объявлена в первую очередь.
Такое поведение очень заметно в обратных вызовах и замыканиях.
Строгая запись
Ограниченный режим JavaScript.
Цель: упростить написание безопасного JavaScript.
Строгий режим превращает плохие практики в JavaScript в ошибки.
Не позволяйте разработчикам использовать синтаксис, который станет недействительным в будущих разработках JavaScript.
Например, он не позволяет создавать переменные без ключевого слова var (переменная должна быть объявлена).
Другим примером может быть то, что он перестанет ссылаться на объект окна как «это» из внешних экземпляров объекта.
Код внутри функции будет в строгом режиме, если вы используете «use strict»; внутри него.
‘use strict’ используется вне метода exclaim() в приведенной выше программе. В результате строгий режим применим только внутри функции.
Как видите, strict используется без объявления в начале программы.
Вы не можете использовать переменную, не объявив ее внутри функции, если вы объявили «use strict» в начале программы.
Закрытие
Закрытие JavaScript — это функция, которая возвращает другую функцию.
В JavaScript замыкание используется для инкапсуляции переменных в функцию и ограничения доступа к ней извне.
JavaScript создает среду со всеми локальными переменными из внешней функции при создании внутренней функции. Закрытие — это сочетание этой среды и внутренней функции.
Итак, давайте рассмотрим пример,
name — это локальная переменная, созданная с помощью Person(), а getName — это функция, созданная с помощью Person() (). Функция getName () — это внутренняя функция, определенная внутри Person (), которую можно использовать только в теле метода Person (). Функция getName () не имеет собственных локальных переменных. Однако, поскольку внутренние функции имеют доступ к переменным внешних функций, getName () может получить доступ к имени переменной, определенной в родительской функции, Person ().
Обратный звонок и обещания
JavaScript является асинхронным. Все операции ввода-вывода в JavaScript реализованы как асинхронные по своей природе.
Причина этого в том, что JavaScript является однопоточным языком, если операции ввода-вывода удерживают поток до тех пор, пока он не завершится. JavaScript не будет хорошо работать как язык программирования.
Но асинхронная операция создает трудности, когда нам нужно выполнить синхронную обработку с использованием данных.
Это решается с помощью обратных вызовов и промисов.
Обратный звонок
Обратный вызов — это функция, которая передается асинхронной задаче, и по завершении функция будет выполнена.
Пример обратного вызова: -
Функции также можно передавать в качестве параметров другим функциям и вызывать из внешних функций. В результате callback — это функция, которая отправляется в другую. Он выполнит вторую функцию после завершения первой.
Обещание
Обещание — это объект, возвращаемый асинхронными задачами. У Promise есть свойства для синхронной работы с асинхронными операциями.
Пример обещания:
В следующем промисе, если условие истинно, разрешить обещание и вернуть «Промис выполнен», в противном случае вернуть «Промис отклонен». Теперь, когда мы установили наш первый промис, давайте применим его.
Мы используем then() для разрешения и catch() для отклонения приведенной выше конструкции Promise.
Управление версиями
Почему?
› Упрощенное резервное копирование и централизованное хранилище исходного кода.
› Простая совместная разработка.
›Обзор внесенных в файл изменений.
>Контроль доступа.
›Устранение конфликтов.
Основные команды Git
✍️Git инициировать
›Создает новый репозиторий git
✍️Гит-клон
›Утилита командной строки git, используемая для выбора существующего репозитория и создания клона или копии целевого репозитория.
✍️Гит добавить
›добавляет изменение рабочего каталога в тестовую область.
✍️Гит этап
›В git промежуточный шаг позволяет вам продолжать вносить изменения в рабочий каталог, но при этом позволяет записывать изменения в второстепенных коммитах, когда вы решили взаимодействовать с контролем версий.
✍️Git коммит
›Изменения в репозитории должны фиксироваться
✍️Git push
›Удаленные ссылки, а также связанные с ними объекты должны быть обновлены.
✍️Git Pull
›Используется для обновления локальной версии репозитория с удаленного
✍️Git ветка
›Создает новую ветку для существующего репозитория
✍️Гит-оформить заказ
›Перемещается между ветвями, созданными ветвью git.
✍️Git слияние
›Возьмите независимую линию разработки, созданную веткой git, и интегрируйте их в одну ветку
NoSQL
✍️Разница между SQL и NoSQL
✍️Преимущества NoSQL
(i) Гибкая модель данных:
›Базы данных NoSQL очень гибкие, поскольку они могут хранить и комбинировать данные любого типа, как структурированные, так и неструктурированные, в отличие от реляционных баз данных, которые могут хранить данные только в структурированном виде.
(ii) Развивающаяся модель данных:
›Базы данных NoSQL позволяют динамически обновлять схему в соответствии с меняющимися требованиями, гарантируя, что это не приведет к прерыванию или простою вашего приложения.
(iii) Эластичная масштабируемость:
›Базы данных NoSQL можно масштабировать, чтобы приспособиться к любому типу роста данных при сохранении низкой стоимости.
(iv) Высокая производительность:
›Базы данных NoSQL рассчитаны на высокую производительность, измеряемую как пропускной способностью (это показатель общей производительности), так и задержкой (это задержка между запросом и фактическим ответом).
(v) Открытый исходный код:
›Базы данных NoSQL не требуют больших лицензионных отчислений и могут работать на недорогом оборудовании, что делает их развертывание рентабельным.
✍️Недостаток NoSQL
(i) Отсутствие стандартизации:
›Не существует стандарта, определяющего правила и роли баз данных NoSQL. Структура и языки запросов баз данных NoSQL сильно различаются в разных продуктах NoSQL — гораздо больше, чем среди традиционных баз данных SQL.
(ii) Резервное копирование базы данных:
›Резервные копии являются недостатком баз данных NoSQL. Хотя некоторые базы данных NoSQL, такие как MongoDB, предоставляют некоторые инструменты для резервного копирования, эти инструменты недостаточно развиты, чтобы обеспечить надлежащее полное решение для резервного копирования данных.
(iii) Согласованность:
› NoSQL ставит на первое место масштабируемость и производительность, но когда дело доходит до согласованности данных, NoSQL не уделяет особого внимания, поэтому делает его менее безопасным по сравнению с реляционной базой данных, например, в базах данных NoSQL, если вы снова вводите один и тот же набор данных. , он примет это без каких-либо ошибок, в то время как реляционные базы данных гарантируют, что никакие повторяющиеся строки не попадут в базы данных.
МонгоБД
✍️База данных документов NoSQL.
✍️Мощные возможности запросов с агрегированием с использованием JavaScript.
✍️Используйте JavaScript-движок Spider Monkey.
✍️Высокая доступность с наборами реплик.
✍️Чтение и запись на первичном по умолчанию.
✍️В конечном счете согласуется со вторичными экземплярами.
✍️Встроенное файловое хранилище под названием Grid File System.
Запросы MongoDB
✍️Вставка
✍️Найти
✍️Обновление
✍️Удалить