Разработка программного обеспечения — это, по сути, наука, требующая больших человеческих усилий. Это означает, что это требует знания как методов, так и технологий, а также понимания проблемы и способности принимать решения для реализации решения на нескольких уровнях абстракции. Программирование во многом зависит от того, как думает разработчик. С годами, в каждом контексте и на каждом языке, появились рекомендации и решения для решения повторяющихся проблем. Знание этих шаблонов поможет вам определить, когда их применять, и ускорить свое развитие. С другой стороны, принципы — это руководящие концепции, которые следует применять на каждом этапе процесса и больше связаны с тем, как вы подходите к процессу.
В этой главе мы рассмотрим неисключительный и неисчерпывающий список принципов и шаблонов, которые распространены при разработке приложений Vue 3.
Принципы
• Разделение задач
• Композиция важнее наследования
• Единая ответственность
• Инкапсуляция
• KIC – держите его в чистоте
• DRY– не повторяйтесь
• KISS – будь проще, глупый
• Код для следующего
• Separation of concerns
• Composition over inheritance
• Single responsibility
• Encapsulation
• KIC – keep it clean
• DRY – don’t repeat yourself
• KISS – keep it simple stupid
• Code for the next
Паттерны
• Синглтон
• Внедрение зависимости
• Наблюдатель
• Команда
• Прокси
• Декоратор
• Фасад
• Обратные вызовы
• Обещания
• Singleton
• Dependency injection
• Observer
• Command
• Proxy
• Decorator
• Façade
• Callbacks
• Promises
Понимание этих принципов и закономерностей поможет вам использовать структуру более эффективно и
чаще всего это помешает вам «изобрести велосипед». Вместе с первой главой
это завершит основную часть книги и даст вам основу для дальнейшего практического применения.
части и примеры реализации приложений в остальной части книги.
Каковы принципы проектирования программного обеспечения?
В разработке программного обеспечения принципы проектирования — это концептуальные рекомендации высокого уровня, которые должны применяться к
весь процесс. Не в каждом проекте будут использоваться одни и те же принципы, и это не обязательные правила.
быть исполнено. Они могут появиться в проекте от архитектуры до пользовательского интерфейса (UI).
и последний бит кода. На практике некоторые из этих принципов также могут влиять на атрибуты программного обеспечения.
такие как ремонтопригодность и возможность повторного использования.
Неисключительный список принципов дизайна
Принципы проектирования несколько различаются в зависимости от контекста, предметной области и даже команды, в которой вы работаете.
часть того времени. Таким образом, принципы, включенные в эту главу, не являются исключительными.
Разделение задач
Это, пожалуй, самый важный принцип в разработке программного обеспечения. Разделение задач подразумевает
что система должна быть разделена на подсистемы элементов, сгруппированных по их функциям или услугам (т.
беспокойство). Например, мы можем рассматривать организм человека как систему, состоящую из множества подсистем.
(дыхательная, кровеносная, пищеварительная и др.). Они, в свою очередь, интегрируются различными органами, которые
состоят из тканей и так далее, вплоть до мельчайших клеток. Следуя той же идее в программном обеспечении,
приложение можно разделить на элементы, сгруппированные по интересам, начиная с большой архитектуры и заканчивая
вплоть до последней функции. Без этого разделения сложности на управляемые части создание
Функциональная система будет намного сложнее, если вообще возможно.
В общем, применение этого принципа начинается с общей картины того, какой должна быть система.
изучает, что следует сделать для достижения этой цели, а затем разбивает это на управляемые рабочие части.
В качестве примера, вот грубое графическое представление разделения задач для веб-приложения.
В каждом блоке на этой диаграмме обозначена отдельная проблема, которую, в свою очередь, можно разбить на более мелкие.
функциональные части. Более того, вы можете увидеть, как этот принцип позволяет вам определить интегрирующее
части системы.
Если бы нам пришлось углубиться в любой из этих маленьких ящиков в соответствующих областях, мы могли бы
все еще находим больше проблем, которые нужно разделить, пока мы не достигнем неделимого атомного элемента (компонента или
функция, например). Этот принцип во многом связан с другими принципами, такими как
абстракция и единая ответственность. Мы рассмотрим их далее в этой же главе.
Композиция важнее наследования
Принцип композиции над наследованием исходит непосредственно из объектно-ориентированного программирования.
(ООП). Он гласит, что объект должен пытаться использовать функциональность других объектов, когда это необходимо.
ссылаться на них или создавать их экземпляры вместо создания большого и сложного генеалогического древа наследования.
классы для добавления такой функциональности. Итак, JavaScript по своей сути является функциональным языком, хотя
он поддерживает несколько парадигм, включая функции ООП, поэтому этот принцип также применим. Есть
одно предупреждение для тех, кто переходит от ООП к JavaScript, и оно заключается в том, чтобы избежать искушения
рассматривать JavaScript как чистый язык ООП. Это может создать ненужную сложность вместо
пользуясь достоинствами языка.
В Vue 3 нет расширения или наследования компонентов. Когда нам нужны общие или унаследованные
функциональности, у нас есть хороший набор инструментов для замены парадигмы наследования. мы увидим позже
как мы можем соблюсти этот принцип, используя составные компоненты, в главе 4 «Пользовательский интерфейс».
Композиция с компонентами.
Принцип единой ответственности
Этот принцип можно найти как в ООП, так и в функциональном программировании. Проще говоря, там говорится, что
класс, метод, функция или компонент должны иметь дело только с одной ответственностью или функциональностью. Если
вы работали в других дисциплинах и языках, это естественно. Многоцелевые функции
его сложно поддерживать, и он имеет тенденцию выходить из-под контроля, особенно в таком языке, как JavaScript, который
свободно типизированный и очень динамичный. Та же концепция применима непосредственно к компонентам Vue 3. Каждый
компонент должен выполнять одну конкретную операцию и избегать попыток сделать слишком много самостоятельно. На практике, когда компонент выходит за пределы определенной области, лучше всего разделить его на несколько компонентов.
или извлеките поведение во внешние модули. Бывают случаи, когда у вас может получиться многотысячная сумма.
строковый компонент, но по моему опыту это редко бывает необходимо и может и должно быть
избегал. Однако следует предупредить, что слишком большая специфичность может также привести к ненужной сложности.
В качестве примера давайте представим себе экран входа в систему, на котором также отображается опция регистрации. Этот подход
сегодня распространено на многих сайтах. Вы можете включить все функции в один компонент,
но это нарушит этот принцип. Лучшей альтернативой было бы разделить компоненты как минимум на
три компонента для этой задачи:
• Родительский компонент, который обрабатывает логику пользовательского интерфейса. Этот компонент решает, когда показывать/скрывать
компоненты входа и регистрации.
• Дочерний компонент, который обрабатывает функцию входа.
• Дочерний компонент, выполняющий функцию регистрации.
Подумайте, что вы сможете быстро осознать преимущества этого принципа. Это упрощает управление кодом,
поддерживать и адаптироваться, поскольку веб-приложения имеют тенденцию очень и очень быстро видоизменяться и развиваться.
Дайте компонентам единую ответственность и функциональность. Избегайте гигантского монолита
компонентов как можно больше.
Инкапсуляция
Инкапсуляция — это идея, согласно которой вы должны обернуть данные и методы так, чтобы они действовали как единое целое, в то время как
предоставление четко определенного интерфейса прикладного программирования (API). Зачастую это делается в форме
классов, модулей или библиотек. JavaScript не является исключением, и настоятельно рекомендуется
следуйте этому принципу. В Vue 3 эта концепция применима не только к компонентам, но и к стилям CSS и
HTML. Внедрение однофайловых компонентов является наглядным примером того, как фреймворк способствует
этот принцип в действии и насколько он важен для сегодняшнего развития. Только с несколькими крайними случаями
ситуациях мы должны рассматривать компоненты (UI) как черные ящики, которые получают входящие параметры
и предоставить исходящие данные. Другие компоненты не должны знать о своей внутренней работе, только
API. По мере создания примеров приложений в этой книге вы увидите этот принцип в действии.
KIC – keep it clean
Этот принцип относится главным образом к тому, как вы пишете код. Здесь я должен подчеркнуть, что KIC применяется
сразу на две категории, которые сильно влияют на веб-приложения и приложения Vue 3:
• Как вы форматируете свой код
• Как вы убираете события и переменные
Первый пункт включает использование соглашений о коде, комментариев и отступов для организации
код и логическая группировка функций. Например, если у вас есть методы, которые занимаются созданием,
операций чтения, обновления и удаления (CRUD), лучше всего размещать их рядом друг с другом в
код, а не распространяться по исходному файлу. Множество интегрированных сред разработки (IDE).
содержат функции для свертывания или расширения внутреннего кода функций. Это помогает быстро просмотреть и
найдите разделы в коде со схожей логикой.
Вторая часть этого принципа связана с обработкой памяти и ссылок. JavaScript имеет очень
хороший сборщик мусора, функция которого — отбрасывать неиспользуемые данные для освобождения памяти. Однако,
бывают случаи, когда алгоритм не может освободить ресурсы, потому что ссылка
все еще в ожидании. Если вы работали с другими языками, например C/C++, эта проблема может показаться вам знакомой.
так как вам нужно вручную резервировать и освобождать память, когда она не используется. В JavaScript, если вы зарегистрируете
функции для прослушивания события, лучше всего вручную отменить ее регистрацию в соответствующем событии жизненного цикла
ваш компонент, когда он больше не нужен. Это предотвратит утечки памяти и ее нерациональную трату.
также предотвратить некоторые угрозы безопасности (которые выходят за рамки этой книги).
Мы рассмотрим жизненный цикл компонента в главе 4 «Композиция пользовательского интерфейса с компонентами».
а пока возьмите следующий пример как хорошее применение этого принципа и сохраните его как можно лучше.
упражняться. В этом примере мы создадим составной компонент, который будет определять, когда размер окна
изменения, поэтому в разделе настройки скрипта мы найдем что-то вроде этого:
1. Регистрирует функцию для события изменения размера объекта окна во время состояния монтирования.
2. Отменяет регистрацию события перед отмонтированием компонента.
<script setup>
import {onMounted, onBeforeUnmount} from "vue"
onMounted(()=>{
window.addEventListener("resize", myFunction)
})
onBeforeUnmount(()=>{
window.removeEventListener("resize", myFunction)
})
function myFunction(){
// Do something with the event here
}
</script>
Функции onMounted и onBeforeUnmount являются частью платформы Vue 3 и
инициируется соответствующим событием жизненного цикла компонента. Здесь мы присоединяем нашу функцию к изменению размера
событие, когда компонент монтируется в объектную модель документа (DOM), и мы просто выпускаем его
прежде чем он будет удален. Важно помнить, что нужно убирать за собой и содержать его в чистоте.
DRY – don’t repeat yourself
Этот принцип довольно известен, почти что превратился в клише. К сожалению, это легко забывается.
Авторство принадлежит Эндрю Ханту и Дэвиду Томасу, которые использовали его в книге «Программист-прагматик».
В основном думают, что нельзя писать одно и то же дважды, и это не за горами, но это выходит за рамки этого. Это
включает в себя идею предотвращения избыточности в процессе, а также в логике приложения.
Основная идея заключается в том, что каждый процесс, выполняющий бизнес-логику, должен существовать только в одном месте вашей системы.
все приложение.
Например, большинство веб-приложений имеют асинхронное соединение с сервером через
использование API. В приложении также может быть несколько элементов, которые будут использовать или должны использовать
это связь с удаленным компьютером/сервером. Если вы собирались закодировать весь код/логику в
общаться с сервером в каждом компоненте, мы получим не только дублирование кода
но и логика приложения. Поддержание такой системы открыло бы двери для огромного количества
негативных побочных эффектов и проблем безопасности, плохого пользовательского опыта и многого другого. Согласно этому
В принципе, лучший подход — абстрагировать весь коммуникационный код, связанный с API сервера, в один
модуль или класс. На практике в JavaScript это можно даже делегировать веб-воркеру в отдельном разделе.
нить. Мы рассмотрим эту реализацию позже в главе 8 «Многопоточность с помощью веб-воркеров».
Как правило, если вы видите, что пишете «один и тот же код» в разных компонентах или
классов, это очевидная возможность абстрагировать функциональность в отдельный модуль или компонент.
KISS – keep it simple and short
Этот принцип не является исключительным для сферы проектирования программного обеспечения. Его придумали ВМС США еще в
60-е годы (по данным Википедии, https://en.wikipedia.org/wiki/KISS_principle).
Идея основана на чистом здравом смысле: лучше создавать простые, небольшие функциональные детали, которые работают вместе.
чем пытаться создать большую и сложную программу за один раз. Кроме того, алгоритмы должны быть реализованы.
самым простым и эффективным способом. В веб-разработке этот принцип важен. Современная сеть
приложения состоят из сотен рабочих частей, распределенных по множеству компьютеров, серверов,
и среды. Чем сложнее реализация системы или кода, тем сложнее ее
поддерживать и адаптировать.
Однако есть предупреждение. Простота не означает чрезмерного упрощения или ненужности.
сегрегация. Слишком много мелких деталей могут привести к ненужной сложности системы. Применение
Принцип KISS означает оставаться в той золотой середине, где все управляемо и легко.
понимать.
Code for the next
Этот принцип заключается в том, что вы должны сделать свой код читаемым и понятным для кого-то.
еще, кроме тебя. Соглашения об именах, логический поток и межстрочные комментарии — все это часть этого. Нет
только в том случае, когда вам может потребоваться делегировать свой код другому, но также и когда вы вернетесь
через год-два по тому же коду. Меньше всего вам хочется тратить время на размышления о том, что
прошлое, неопытное, которое вы сделали с помощью этой умной строки кода-спагетти. Умные разработчики пишут код так, как будто они
собирались научить кого-то другого, просто и элегантно. Особенно, если вы используете или участвуете в
открытый исходный код, этот принцип жизненно важен для группового сотрудничества. В данном случае стоит упомянуть
Принцип бойскаутов, который аналогичен, но применяется в группах. В нем говорится, что когда вы обнаружите трудно читаемую
или код «спагетти», вы реорганизуете его, чтобы сделать его чистым.
Поддерживайте чистоту своего кода с помощью комментариев в исходном коде и документации, объясняющей вашу логику, поскольку
если учить кого-то другого. Чаще всего вы будете обучать себя.
Принципы проектирования применимы ко многим различным сценариям, некоторые из которых выходят за рамки практики разработки программного обеспечения.
Важно учитывать их до тех пор, пока они не станут второй натурой. В целом применение этих
и другие принципы, а также применение шаблонов проектирования, оказывают важное влияние на
ваше профессиональное развитие.