Обычно во вступлении мы рассказываем то, что ожидает вас внутри курса, но здесь я решил
рассказать кое-что важное. Попробуйте самостоятельно ответить на вопрос. Какая основная
задача программиста?
Вероятно, вы ответите "писать код" и будете не правы. Писать код это всего лишь средство,
причём не единственное. Также часто решением задачи является удаление кода или, вообще,
отсутствие кода, и всё это тоже область компетенции программиста.
Начать нужно с того, что программирование, как таковое, это не цель, это всего лишь
средство достижения бизнес-целей той компании, которая вас нанимает. В конечном итоге
всё программное обеспечение так или иначе служит удовлетворению потребностей бизнеса:
увеличению прибыли, снижению издержек. Хорошая статья об этом есть в нашем блоге.
На практике это означает очень простую вещь, перед тем как бросаться писать код,
нужно понять цель того, что вам нужно сделать. Хочу ещё раз акцентировать ваше внимание, на том,
что цель это зачем мы это делаем, а не что нужно сделать. У меня
есть хорошая аналогия, которую мы постоянно наблюдаем в своей жизни. Вспомните приходы
к доктору. Многие люди пытаются рассказывать доктору не только симптомы, но и
выдвигают гипотезы, а некоторые прямо утверждают, что у них конкретная болезнь и, более того,
они знают, как лечиться. Доктора обычно пропускают это мимо ушей, потому что его
задача понять истинную причину. То же самое часто происходит в разработке. К вам приходит
заказчик и говорит, что нужно сделать. Например: "Вася, добавь две колонки в базу".
Возникает парадоксальная ситуация, чем более технически подкован заказчик тем, как правило,
он больше пытается продавливать конкретные решения, вместо того, чтобы описывать свою
бизнес-задачу (цель), оставляя вам манёвр для решения.
Избежать этого невозможно, никто и никогда не будет давать идеальных задач, которые
созданы исходя из бизнес-целей. Такое, конечно же, бывает, но гораздо реже, чем вам
может показаться. В итоге бизнес-аналитикой занимается разработчик (кроме сложных случаев),
и это нормально. Докопавшись до сути, может оказаться так, что кода писать не надо вообще
и достаточно поменять правила игры.
Дальше по курсу мы будем исходить из того, что все цели уже определены и нужно именно
писать код, но перед тем, как мы двинемся дальше, я расскажу о том, как смотреть
на мир глазами бизнеса и почему это полезно.
Подумайте вот о чём. Откуда бизнес узнает, что нужно делать? Работая на дядю может сложиться
впечатление, что там наверху умные люди, которые знают, что делают. На самом деле они не знают.
Представьте, что вы начинаете с нуля свой стартап. После непродолжительного анализа станет
понятно, что основная сложность не в том, чтобы понять "что делать", а в том, чтобы понять
"что не делать". На эту тему есть обязательная книга к прочтению, которая поменяет
ваше мировоззрение: "Бизнес с нуля. Метод Lean Startup."
Lean Startup
Не обращайте внимание на слово "стартап" в заголовке, эта методология одинаково хорошо работает
и для больших бизнесов и для молодых проектов. Удивительно, но основная идея этого подхода
пришла из научного мира и называется "научный метод":
Нау́чный ме́тод — совокупность основных способов получения новых знаний и методов решения
задач в рамках любой науки.
Метод включает в себя способы исследования феноменов, систематизацию, корректировку новых
и полученных ранее знаний. Умозаключения и выводы делаются с помощью правил и принципов
рассуждения на основе эмпирических (наблюдаемых и измеряемых) данных об объекте. Базой
получения данных являются наблюдения и эксперименты. Для объяснения наблюдаемых фактов
выдвигаются гипотезы и строятся теории, на основании которых в свою очередь строится
математическое описание — модель изучаемого объекта.
Первое. Логика контринтуитивна. Понять, что нужно вашим пользователям заранее и без общения
с ними, практически невозможно. Используя lean startup мы выдвигаем гипотезы, а не
продумываем конкретные решения. Пример гипотез:
Пользователи хотят заказывать такси без необходимости звонить оператору и диктовать адрес.
Пользователю удобнее оплачивать такси с карты, чем наличными
Проницательный читатель увидит, что при таком подходе, нет цели реализовать сразу всё, от и
до продумав все части программы. Задачей станет реализовать только то, что может помочь
подтвердить или опровергнуть гипотезу. Ведь если гипотеза не верна, это автоматически означает,
что нужно корректировать все дальнейшие планы. В противном случае будут большие потери.
После того, как гипотеза готова, делается всё необходимое для её проверки. Многие гипотезы,
по факту, не требуют написания кода вообще. Например, гипотеза про удобство оплаты такси
картой проверяется звонками друзьям/постами в соцсети. Согласитесь, что это сильно дешевле,
проще и быстрее, чем месяцами писать приложение, а потом увидеть, что это никому не нужно.
На выходе получается цепочка: Гипотеза -> Реализация (если нужно) -> Анализ данных. Повторяя
эту цепочку снова и снова, мы получаем продукт, который действительно работает и отвечает
бизнес-целям.
Ключевые слова для самообразования:
- Customer development
- Business Model Canvas
- Minimum Viable Product
- Pivot
SMART
Когда речь идёт про уже существующий бизнес или, даже, личные цели, то подойдёт такой
подход как SMART:
Это мнемоническая аббревиатура, используемая в менеджменте и проектном управлении для
определения целей и постановки задач:
* конкретный (specific);
* измеримый (measurable);
* достижимый (attainable);
* значимый (relevant);
* соотносимый с конкретным сроком (time-bounded)
Этот подход хорошо расписан в вики, поэтому не буду заниматься копипастой.
Impact mapping
Impact Mapping простая и эффективная техника для определения целей заказчика
и передача этих целей разработчикам.
Impact Mapping — это диаграмма связей (mind map) по целям проекта с картой влияний, которые должны
подтолкнуть бизнес заказчика к достижению целей.
Why?
Центральный элемент нашей карты, который отвечает на ключевой вопрос:
Зачем мы это делаем? Это цель, которую бизнес пытается достичь.
Who?
На первом уровне мы отвечаем на вопросы: Кто поможет достичь желаемого результата?
Кто может помешать? Кто пользователи нашего продукта? Сюда войдут все заинтересованные стороны, которые могут повлиять на цели бизнеса.
How?
На втором уровне мы должны описать воздействия, которые должны оказать заинтересованные
стороны, чтобы бизнес достиг целей. Мы ищем ответ на вопросы: Как они помогут бизнесу
достичь целей? Как они могут помешать успеху проекта?
What?
После ответа на основные вопросы можно обсудить конкретные задачи. Третий уровень
отвечает на вопросы: Что мы можем сделать как организация или команда разработки,
чтобы создать необходимые воздействия? Здесь будет описан конечный результат нашей работы.
Подробнее об этом подходе можно прочитать в
замечательной статье Александра Бындю на Хабре.
User Story Mapping
После определения карты влияний на цели можно определить роли пользователей,
как они будут взаимодействовать с системой, важность задач, план релизов и т.д.
Цель user story mapping в том, чтобы приоритезировать пользовательские истории
по важности.
Пример пользовательской истории:
Я, как менеджер по продажам, хочу видеть отчёт по интересам клиентов в курсах, для того,
чтобы принять решение о создании нового курса и приглашения этих клиентов принять в нём участие.
Об этой полезной технике можно найти много статей на просторах сети. Подробнее
на ней останавливаться не будем, пора переходить к самому курсу).
Проект: Электронная продажа билетов
На протяжении курса мы будем создавать систему для продажи билетов в кинотеатре
через интернет. Бизнес-анализ тоже будет присутствовать, но в очень ограниченном
варианте. Основной упор на то, как писать код.
Основные темы
По пути разберём много страшных слов, и я понимаю, что многие вещи, о которых будет говориться,
вызовут ещё больше вопросов, чем ответов. Цель этого курса показать новые горизонты,
а не дать всеобъемлющее руководство к действию. Этим курсом ваш путь только начинается.
- Domain-Driven Design
- Entity, Value-Object
- Repository
- Service Layer
- Inversion Of Control
- Dependency Inversion Principle
- Dependency Injection Container
- FSM
Дополнительные темы
В процессе используем множество разных библиотек, таких как:
- bottlejs
- uuid/validate.js
- lodash/date-fns
<!DOCTYPE html>
<html class="h-100" data-bs-theme="light" data-mantine-color-scheme="light" lang="ru" prefix="og: https://ogp.me/ns#">
<head>
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<link crossorigin="true" href="https://cdn.hexlet.io" rel="preconnect">
<link href="https://mc.yandex.ru" rel="preconnect">
<meta content="aa2vrdtq64dub8knuf83lwywit311w" name="facebook-domain-verification">
<link href="/favicon.ico" rel="icon" sizes="any">
<link href="/favicon.svg" rel="icon" type="image/svg+xml">
<link href="/apple-touch-icon.png" rel="apple-touch-icon">
<link href="/manifest.webmanifest" rel="manifest">
<script>
//<![CDATA[
window.gon={};gon.ym_counter="25559621";gon.is_bot=true;gon.applications={};gon.current_user={"id":null,"last_viewed_notification_id":null,"email":null,"state":null,"first_name":"","last_name":"","created_at":"2026-02-26 20:38:23 UTC","current_program":null,"current_team":null,"full_name":"","guest":true,"can_use_paid_features":false,"is_hexlet_employee":false,"sanitized_phone_number":"","can_subscribe":true,"can_renew_education":false};gon.token="PJuMh2Nk0KKPXq_2hVlrDpTGue6KdR_Xrb_cWcEoTxPTSkewkRp9wjkdi26JVpt5VM-URIJC4XUQX0YNky-ofQ";gon.locale="ru";gon.language="ru";gon.theme="light";gon.rails_env="production";gon.mobile=false;gon.google={"analytics_key":"UA-1360700-51","optimize_key":"GTM-5QDVFPF"};gon.captcha={"google_v3_site_key":"6LenGbgZAAAAAM7HbrDbn5JlizCSzPcS767c9vaY","yandex_site_key":"ysc1_Vyob5ZPPUdPBsu0ykt8bVFdzsfpoVjQChLGl2b4g19647a89","verification_failed":null};gon.social_signin=false;gon.typoreporter_google_form_id="1FAIpQLSeibfGq-KvWQ2Fyru-zkFFRVTLBuzXAHAoEyN1p49FtDmNoNA";
//]]>
</script>
<meta charset="utf-8">
<title>Введение | JS: Предметно-ориентированное проектирование</title>
<meta name="description" content="Введение / JS: Предметно-ориентированное проектирование: Знакомимся с целями и задачами курса">
<link rel="canonical" href="https://ru.hexlet.io/courses/js-ddd/lessons/intro/theory_unit">
<meta name="robots" content="noarchive">
<meta property="og:title" content="Введение">
<meta property="og:title" content="JS: Предметно-ориентированное проектирование">
<meta property="og:description" content="Введение / JS: Предметно-ориентированное проектирование: Знакомимся с целями и задачами курса">
<meta property="og:url" content="https://ru.hexlet.io/courses/js-ddd/lessons/intro/theory_unit">
<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="k1rC-lJ7HVv6iwIp2g9K27K0IJPku8zD5_4iKsPeS3l8iwnNoAWwO0zIJrHWALqscr0NOeyMMmFaHrh-kdmsFw" />
<script src="/vite/assets/inertia-DfXos102.js" crossorigin="anonymous" type="module"></script><link rel="modulepreload" href="/vite/assets/chunk-DsPFFUou.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/preload-helper-BJ4cLWpC.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/init-BrRXra1y.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/ahoy-DrlRQ-1D.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/analytics-cb8xch9l.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/ErrorFallbackBlock-naDSYSy9.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Surface-DL2bpZA-.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/gon-D3e4yh1x.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/mantine-CGMYrt2Y.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/utils-DRqSHbQE.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/routes-CCH8ilKF.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/extends-C-EagtpE.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/inheritsLoose-BBd-DCVI.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/objectWithoutPropertiesLoose-DRHXDhjp.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/index.esm-DAqKOkZ0.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Button-CGPUux8l.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/CloseButton-D1euiPao.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Group-BX48WcuU.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Loader-BQEY8g6v.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Modal-Cy3HByv7.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/OptionalPortal-1Hza5P2w.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Stack-CtjJzfw4.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Textarea-Ck64llAy.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Box-B5-OOzBf.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/DirectionProvider-Dc9zdUke.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/events-DJQOhap0.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/use-reduced-motion-D2owz4wa.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/use-disclosure-zKtK5W1r.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/use-hotkeys-Cnc_Rwkb.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/random-id-DOQyszCZ.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/notifications.store-C-3AFSMn.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/exports-C_MrNx_T.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/axios-BEvgo0ym.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/dayjs.min-BkKovM-s.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/i18next-BlSq9s7B.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/client-U9M77rxp.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-dom-DaLxUz_h.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/useTranslation-Bx1Cdrkz.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/compiler-runtime-6XxiPFnt.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/jsx-runtime-CwjcCKJi.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-CkL4ZRHB.js" as="script" crossorigin="anonymous">
<link rel="stylesheet" href="/vite/assets/application-BqhCP46M.js" />
<script src="/vite/assets/application-Df9RExpe.js" crossorigin="anonymous" type="module"></script><link rel="modulepreload" href="/vite/assets/chunk-DsPFFUou.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/autocomplete-VMNbxKGl.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/routes-CCH8ilKF.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/createPopper-C3aM9r1M.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/js.cookie-D1-O8zkX.js" as="script" crossorigin="anonymous"><link rel="stylesheet" href="/vite/assets/application-C8HjmMaq.css" media="screen" />
<script>
window.ym = function(){(ym.a=ym.a||[]).push(arguments)};
window.addEventListener('load', function() {
setTimeout(function() {
ym.l = 1*new Date();
ym(window.gon.ym_counter, "init", {
clickmap: true,
trackLinks: true,
accurateTrackBounce: true,
webvisor: true
});
// Загружаем скрипт
var k = document.createElement('script');
k.async = 1;
k.src = 'https://mc.yandex.ru/metrika/tag.js';
document.head.appendChild(k);
ym(window.gon.ym_counter, 'getClientID', function(clientID) {
window.ymClientId = clientID;
});
}, 1500);
});
</script>
<!-- Google Tag Manager - deferred -->
<script>
// dataLayer stub сразу — пуши работают до загрузки скрипта
window.dataLayer = window.dataLayer || [];
// Сам скрипт — отложенно после load
window.addEventListener('load', function() {
setTimeout(function() {
dataLayer.push({'gtm.start': new Date().getTime(), event: 'gtm.js'});
var j = document.createElement('script');
j.async = true;
j.src = 'https://www.googletagmanager.com/gtm.js?id=GTM-WK88TH';
document.head.appendChild(j);
}, 1500);
});
</script>
<!-- End Google Tag Manager -->
</head>
<body>
<noscript>
<div>
<img alt="" src="https://mc.yandex.ru/watch/25559621" style="position:absolute; left:-9999px;">
</div>
</noscript>
<header class="sticky-top bg-body">
<nav class="navbar navbar-expand-lg">
<div class="container-xxl">
<a class="navbar-brand" href="/"><img alt="Логотип Хекслета" height="24" src="https://ru.hexlet.io/vite/assets/logo_ru_light-BpiEA1LT.svg" width="96">
</a><button aria-controls="collapsable" aria-expanded="false" aria-label="Меню" class="navbar-toggler border-0 mb-0 mt-1" data-bs-target="#collapsable" data-bs-toggle="collapse">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="collapsable">
<ul class="navbar-nav mb-lg-0 mt-lg-1">
<li class="nav-item dropdown">
<button aria-haspopup class="btn nav-link" data-bs-toggle="dropdown" type="button">
Все курсы
<span class="bi bi-chevron-down align-middle ms-1"></span>
</button>
<ul class="dropdown-menu">
<li>
<a class="dropdown-item d-flex py-2" href="/courses"><div class="fw-bold me-auto">Все что есть</div>
<div class="text-muted">117</div>
</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li class="dropdown-item">
<b>Популярные категории</b>
</li>
<li>
<a class="dropdown-item py-2" href="/courses_devops">Курсы по DevOps
</a></li>
<li>
<a class="dropdown-item py-2" href="/courses_data_analytics">Курсы по аналитике данных
</a></li>
<li>
<a class="dropdown-item py-2" href="/courses_programming">Курсы по программированию
</a></li>
<li>
<a class="dropdown-item py-2" href="/courses_testing">Курсы по тестированию
</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li class="dropdown-item">
<b>Популярные курсы</b>
</li>
<li>
<a class="dropdown-item py-2" href="/programs/devops-engineer-from-scratch">DevOps-инженер с нуля
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/go">Go-разработчик
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/java">Java-разработчик
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/python">Python-разработчик
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/qa-auto-engineer-java">Автоматизатор тестирования на Java
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/data-analytics">Аналитик данных
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/frontend">Фронтенд-разработчик
</a></li>
</ul>
</li>
<li class="nav-item dropdown">
<button aria-haspopup class="btn nav-link" data-bs-toggle="dropdown" type="button">
О Хекслете
<span class="bi bi-chevron-down align-middle"></span>
</button>
<ul class="dropdown-menu bg-body">
<li>
<a class="dropdown-item py-2" href="/pages/about">О нас
</a></li>
<li>
<a class="dropdown-item py-2" href="/blog">Блог
</a></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://special.hexlet.io/hse-research" role="button">Результаты (Исследование)
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://career.hexlet.io" role="button">Хекслет Карьера
</span></li>
<li>
<a class="dropdown-item py-2" href="/testimonials">Отзывы студентов
</a></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://t.me/hexlet_help_bot" role="button">Поддержка (В ТГ)
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://special.hexlet.io/referal-program/?promo_creative=priglasite-druzei&promo_name=referal-program&promo_position=promo_position&promo_start=010724&promo_type=link" role="button">Реферальная программа
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://special.hexlet.io/certificate" role="button">Подарочные сертификаты
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://hh.ru/employer/4307094" role="button">Вакансии
</span></li>
<li>
<span class="dropdown-item d-flex external-link" rel="noopener noreferrer nofollow" data-href="https://b2b.hexlet.io" data-target="_blank" role="button">Компаниям
</span></li>
<li>
<span class="dropdown-item d-flex external-link" rel="noopener noreferrer nofollow" data-href="https://hexly.ru/" data-target="_blank" role="button">Колледж
</span></li>
<li>
<span class="dropdown-item d-flex external-link" rel="noopener noreferrer nofollow" data-href="https://hexlyschool.ru/" data-target="_blank" role="button">Частная школа
</span></li>
</ul>
</li>
<li><a class="nav-link" href="/subscription/new">Подписка</a></li>
</ul>
<ul class="navbar-nav flex-lg-row align-items-lg-center gap-2 ms-auto">
<li>
<a class="nav-link" aria-label="Переключить тему" href="/theme/switch?new_theme=dark"><span aria-hidden="true" class="bi bi-moon"></span>
</a></li>
<li>
<span data-target="_self" class="nav-link external-link" data-href="/u/new" role="button"><span>Регистрация</span>
</span></li>
<li>
<span data-target="_self" class="nav-link external-link" data-href="https://ru.hexlet.io/session/new" role="button"><span>Вход</span>
</span></li>
</ul>
</div>
</div>
</nav>
</header>
<div class="x-container-xxxl">
</div>
<main class="mb-6 min-vh-100 h-100">
<link rel="preload" as="image" href="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDAwNywicHVyIjoiYmxvYl9pZCJ9fQ==--f0b38f0e25ed59255acec6eaeaeec0a99aec453f/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Binary%20code-rafiki.png"/><link rel="preload" as="image" href="/vite/assets/development-BVihs_d5.png"/><div id="app" data-page="{"component":"web/courses/lessons/theory_unit","props":{"errors":{},"locale":"ru","language":"ru","httpsHost":"https://ru.hexlet.io","host":"ru.hexlet.io","colorScheme":"light","auth":{"user":{"id":null,"last_viewed_notification_id":null,"email":null,"state":null,"first_name":"","last_name":"","created_at":"2026-02-26T20:38:23.296Z","current_program":null,"current_team":null,"full_name":"","guest":true,"can_use_paid_features":false,"is_hexlet_employee":false,"sanitized_phone_number":"","can_subscribe":true,"can_renew_education":false}},"cloudflareTurnstileSiteKey":"0x4AAAAAAA15KmeFXzd2H0Xo","vkIdClientId":"51586979","yandexIdClientId":"88d071f1d3384eb4bd1deb37910235c7","formAuthToken":"yArh9e7LOvQvabhtlZoO3Y9fQ67fDygwjozeTg0NYsUn2yrCHLWXlJkqnPWZlf6qT1ZuBNc41pIzbEQaXwqFqw","topics":[{"id":10355,"title":"Описка \"Кто может поможет\".","plain_title":"Описка \"Кто может поможет\". ","creator":{"public_name":"Andy","id":117329,"is_tutor":false},"comments":[{"creator":{"public_name":"Александр О.","id":61806,"is_tutor":false},"id":21385,"body":"Спасибо, поправил!\n\nP.S. Вы из каких-то принципиальных соображений не проходите челенджи после курсов? :)","topic_id":10355},{"creator":{"public_name":"Andy","id":117329,"is_tutor":false},"id":21391,"body":"Да. Не вижу смысла тратить энергию на искусственные задачи. Нет, понятно, что всё есть вопрос компромисса, нужна практика (\"пиши код, ....\"), но заставить себя нереально. Я лучше вписался бы в какой-нибудь опенсорс (хотя кого я обманываю :), или мотивация придет за свои же деньги (те же Проекты). В общем, как человеку слабохарактерному и ленивому, удовольствия доп. заданий мне недоступны.\n\nКстати, странным кажется упоминание во Введении волшебной техники Impact mapping. По-моему, это вещь чисто сейлзовая, видел подобное когда-то давно на продажных тренингах у одного вендора сетевого оборудования. Выявляешь ответственных лиц и смотришь, как на них можно надавить. Для общего развития любая инфа хороша, но лучше, когда она ближе к делу (конкретному делу).","topic_id":10355}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Введение","entity_url":null,"active":true}},{"id":65552,"title":"При прохождении этого трека нужны какие-то обязательные знания по js?","plain_title":"При прохождении этого трека нужны какие-то обязательные знания по js? ","creator":{"public_name":"Batozhab Budaev","id":453479,"is_tutor":false},"comments":[{"creator":{"public_name":"Ivan Gagarinov","id":75907,"is_tutor":true},"id":138173,"body":"**Bato**, этот курс не входит в какой-либо трек. Если вы имеете ввиду требования для этого курса, то да, нужны базовое знание синтаксиса по js, знание синтаксиса классов.","topic_id":65552}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Введение","entity_url":null,"active":true}},{"id":56479,"title":"Утречка!\n\nА почему здесь и остальных курсах картинки с мелким шрифтом а увеличить без маштаба сайта нельзя? (*взможно не тот топик, извиняюсь*)","plain_title":"Утречка! А почему здесь и остальных курсах картинки с мелким шрифтом а увеличить без маштаба сайта нельзя? (взможно не тот топик, извиняюсь) ","creator":{"public_name":"Roman","id":366856,"is_tutor":false},"comments":[{"creator":{"public_name":"Maksim Litvinov","id":198906,"is_tutor":true},"id":119761,"body":"Добрый день, Роман! Если хотите рассмотреть таблицу подробнее, можете открыть изображение в новой вкладке","topic_id":56479},{"creator":{"public_name":"Roman","id":366856,"is_tutor":false},"id":119765,"body":"Спасибо!","topic_id":56479}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Введение","entity_url":null,"active":true}}],"lesson":{"exercise":null,"units":[{"id":1727,"name":"theory","url":"/courses/js-ddd/lessons/intro/theory_unit"}],"links":[],"ordered_units":[{"id":1727,"name":"theory","url":"/courses/js-ddd/lessons/intro/theory_unit"}],"id":848,"slug":"intro","state":"approved","name":"Введение","course_order":10,"goal":"Знакомимся с целями и задачами курса","self_study":null,"theory_video_provider":null,"theory_video_uid":null,"theory":"Обычно во вступлении мы рассказываем то, что ожидает вас внутри курса, но здесь я решил\nрассказать кое-что важное. Попробуйте самостоятельно ответить на вопрос. Какая основная\nзадача программиста?\n\nВероятно, вы ответите \"писать код\" и будете не правы. Писать код это всего лишь средство,\nпричём не единственное. Также часто решением задачи является удаление кода или, вообще,\nотсутствие кода, и всё это тоже область компетенции программиста.\n\nНачать нужно с того, что программирование, как таковое, это не цель, это всего лишь\nсредство достижения бизнес-целей той компании, которая вас нанимает. В конечном итоге\nвсё программное обеспечение так или иначе служит удовлетворению потребностей бизнеса:\nувеличению прибыли, снижению издержек. [Хорошая статья об этом](https://ru.hexlet.io/blog/posts/developers-business-value) есть в нашем блоге.\n\nНа практике это означает очень простую вещь, перед тем как бросаться писать код,\nнужно понять цель того, что вам нужно сделать. Хочу ещё раз акцентировать ваше внимание, на том,\nчто цель это **зачем** мы это делаем, а не **что** нужно сделать. У меня\nесть хорошая аналогия, которую мы постоянно наблюдаем в своей жизни. Вспомните приходы\nк доктору. Многие люди пытаются рассказывать доктору не только симптомы, но и\nвыдвигают гипотезы, а некоторые прямо утверждают, что у них конкретная болезнь и, более того,\nони знают, как лечиться. Доктора обычно пропускают это мимо ушей, потому что его\nзадача понять истинную причину. То же самое часто происходит в разработке. К вам приходит\nзаказчик и говорит, **что** нужно сделать. Например: \"Вася, добавь две колонки в базу\".\nВозникает парадоксальная ситуация, чем более технически подкован заказчик тем, как правило,\nон больше пытается продавливать конкретные решения, вместо того, чтобы описывать свою\nбизнес-задачу (цель), оставляя вам манёвр для решения.\n\nИзбежать этого невозможно, никто и никогда не будет давать идеальных задач, которые\nсозданы исходя из бизнес-целей. Такое, конечно же, бывает, но гораздо реже, чем вам\nможет показаться. В итоге бизнес-аналитикой занимается разработчик (кроме сложных случаев),\nи это нормально. Докопавшись до сути, может оказаться так, что кода писать не надо вообще\nи достаточно поменять правила игры.\n\nДальше по курсу мы будем исходить из того, что все цели уже определены и нужно именно\nписать код, но перед тем, как мы двинемся дальше, я расскажу о том, как смотреть\nна мир глазами бизнеса и почему это полезно.\n\nПодумайте вот о чём. Откуда бизнес узнает, что нужно делать? Работая на дядю может сложиться\nвпечатление, что там наверху умные люди, которые знают, что делают. На самом деле они не знают.\nПредставьте, что вы начинаете с нуля свой стартап. После непродолжительного анализа станет\nпонятно, что основная сложность не в том, чтобы понять \"что делать\", а в том, чтобы понять\n\"что не делать\". На эту тему есть обязательная книга к прочтению, которая поменяет\nваше мировоззрение: \"Бизнес с нуля. Метод Lean Startup.\"\n\n## Lean Startup\n\n\n\nНе обращайте внимание на слово \"стартап\" в заголовке, эта методология одинаково хорошо работает\nи для больших бизнесов и для молодых проектов. Удивительно, но основная идея этого подхода\nпришла из научного мира и называется \"научный метод\":\n\n```\nНау́чный ме́тод — совокупность основных способов получения новых знаний и методов решения\nзадач в рамках любой науки.\n\nМетод включает в себя способы исследования феноменов, систематизацию, корректировку новых\nи полученных ранее знаний. Умозаключения и выводы делаются с помощью правил и принципов\nрассуждения на основе эмпирических (наблюдаемых и измеряемых) данных об объекте. Базой\nполучения данных являются наблюдения и эксперименты. Для объяснения наблюдаемых фактов\nвыдвигаются гипотезы и строятся теории, на основании которых в свою очередь строится\nматематическое описание — модель изучаемого объекта.\n```\n\nПервое. Логика контринтуитивна. Понять, что нужно вашим пользователям заранее и без общения\nс ними, практически невозможно. Используя lean startup мы выдвигаем гипотезы, а не\nпродумываем конкретные решения. Пример гипотез:\n\n```\nПользователи хотят заказывать такси без необходимости звонить оператору и диктовать адрес.\n\nПользователю удобнее оплачивать такси с карты, чем наличными\n```\n\nПроницательный читатель увидит, что при таком подходе, нет цели реализовать сразу всё, от и\nдо продумав все части программы. Задачей станет реализовать только то, что может помочь\nподтвердить или опровергнуть гипотезу. Ведь если гипотеза не верна, это автоматически означает,\nчто нужно корректировать все дальнейшие планы. В противном случае будут большие потери.\n\nПосле того, как гипотеза готова, делается всё необходимое для её проверки. Многие гипотезы,\nпо факту, не требуют написания кода вообще. Например, гипотеза про удобство оплаты такси\nкартой проверяется звонками друзьям/постами в соцсети. Согласитесь, что это сильно дешевле,\nпроще и быстрее, чем месяцами писать приложение, а потом увидеть, что это никому не нужно.\n\nНа выходе получается цепочка: Гипотеза -> Реализация (если нужно) -> Анализ данных. Повторяя\nэту цепочку снова и снова, мы получаем продукт, который действительно работает и отвечает\nбизнес-целям.\n\nКлючевые слова для самообразования:\n\n* Customer development\n* Business Model Canvas\n* Minimum Viable Product\n* Pivot\n\n## SMART\n\nКогда речь идёт про уже существующий бизнес или, даже, личные цели, то подойдёт такой\nподход как [SMART](https://ru.wikipedia.org/wiki/SMART):\n\n```\nЭто мнемоническая аббревиатура, используемая в менеджменте и проектном управлении для\nопределения целей и постановки задач:\n\n* конкретный (specific);\n* измеримый (measurable);\n* достижимый (attainable);\n* значимый (relevant);\n* соотносимый с конкретным сроком (time-bounded)\n```\n\nЭтот подход хорошо расписан в вики, поэтому не буду заниматься копипастой.\n\n## Impact mapping\n\n\n\nImpact Mapping простая и эффективная техника для определения целей заказчика\nи передача этих целей разработчикам.\n\nImpact Mapping — это диаграмма связей (mind map) по целям проекта с картой влияний, которые должны\nподтолкнуть бизнес заказчика к достижению целей.\n\n### Why?\n\nЦентральный элемент нашей карты, который отвечает на ключевой вопрос:\nЗачем мы это делаем? Это цель, которую бизнес пытается достичь.\n\n### Who?\n\nНа первом уровне мы отвечаем на вопросы: Кто поможет достичь желаемого результата?\nКто может помешать? Кто пользователи нашего продукта? Сюда войдут все заинтересованные стороны, которые могут повлиять на цели бизнеса.\n\n### How?\n\nНа втором уровне мы должны описать воздействия, которые должны оказать заинтересованные\nстороны, чтобы бизнес достиг целей. Мы ищем ответ на вопросы: Как они помогут бизнесу\nдостичь целей? Как они могут помешать успеху проекта?\n\n### What?\n\nПосле ответа на основные вопросы можно обсудить конкретные задачи. Третий уровень\nотвечает на вопросы: Что мы можем сделать как организация или команда разработки,\nчтобы создать необходимые воздействия? Здесь будет описан конечный результат нашей работы.\n\nПодробнее об этом подходе можно прочитать в\n[замечательной статье](https://habrahabr.ru/post/246401/) Александра Бындю на Хабре.\n\n## User Story Mapping\n\n\n\nПосле определения карты влияний на цели можно определить роли пользователей,\nкак они будут взаимодействовать с системой, важность задач, план релизов и т.д.\n\nЦель `user story mapping` в том, чтобы приоритезировать пользовательские истории\nпо важности.\n\nПример пользовательской истории:\n\n```\nЯ, как менеджер по продажам, хочу видеть отчёт по интересам клиентов в курсах, для того,\nчтобы принять решение о создании нового курса и приглашения этих клиентов принять в нём участие.\n```\n\nОб этой полезной технике можно найти много статей на просторах сети. Подробнее\nна ней останавливаться не будем, пора переходить к самому курсу).\n\n\n## Проект: Электронная продажа билетов\n\n\n\nНа протяжении курса мы будем создавать систему для продажи билетов в кинотеатре\nчерез интернет. Бизнес-анализ тоже будет присутствовать, но в очень ограниченном\nварианте. Основной упор на то, как писать код.\n\n## Основные темы\n\nПо пути разберём много страшных слов, и я понимаю, что многие вещи, о которых будет говориться,\nвызовут ещё больше вопросов, чем ответов. Цель этого курса показать новые горизонты,\nа не дать всеобъемлющее руководство к действию. Этим курсом ваш путь только начинается.\n\n* Domain-Driven Design\n* Entity, Value-Object\n* Repository\n* Service Layer\n* Inversion Of Control\n* Dependency Inversion Principle\n* Dependency Injection Container\n* FSM\n\n## Дополнительные темы\n\nВ процессе используем множество разных библиотек, таких как:\n\n* bottlejs\n* uuid/validate.js\n* lodash/date-fns\n"},"lessonMember":null,"courseMember":null,"course":{"start_lesson":{"exercise":null,"units":[{"id":1727,"name":"theory","url":"/courses/js-ddd/lessons/intro/theory_unit"}],"links":[],"ordered_units":[{"id":1727,"name":"theory","url":"/courses/js-ddd/lessons/intro/theory_unit"}],"id":848,"slug":"intro","state":"approved","name":"Введение","course_order":10,"goal":"Знакомимся с целями и задачами курса","self_study":null,"theory_video_provider":null,"theory_video_uid":null,"theory":"Обычно во вступлении мы рассказываем то, что ожидает вас внутри курса, но здесь я решил\nрассказать кое-что важное. Попробуйте самостоятельно ответить на вопрос. Какая основная\nзадача программиста?\n\nВероятно, вы ответите \"писать код\" и будете не правы. Писать код это всего лишь средство,\nпричём не единственное. Также часто решением задачи является удаление кода или, вообще,\nотсутствие кода, и всё это тоже область компетенции программиста.\n\nНачать нужно с того, что программирование, как таковое, это не цель, это всего лишь\nсредство достижения бизнес-целей той компании, которая вас нанимает. В конечном итоге\nвсё программное обеспечение так или иначе служит удовлетворению потребностей бизнеса:\nувеличению прибыли, снижению издержек. [Хорошая статья об этом](https://ru.hexlet.io/blog/posts/developers-business-value) есть в нашем блоге.\n\nНа практике это означает очень простую вещь, перед тем как бросаться писать код,\nнужно понять цель того, что вам нужно сделать. Хочу ещё раз акцентировать ваше внимание, на том,\nчто цель это **зачем** мы это делаем, а не **что** нужно сделать. У меня\nесть хорошая аналогия, которую мы постоянно наблюдаем в своей жизни. Вспомните приходы\nк доктору. Многие люди пытаются рассказывать доктору не только симптомы, но и\nвыдвигают гипотезы, а некоторые прямо утверждают, что у них конкретная болезнь и, более того,\nони знают, как лечиться. Доктора обычно пропускают это мимо ушей, потому что его\nзадача понять истинную причину. То же самое часто происходит в разработке. К вам приходит\nзаказчик и говорит, **что** нужно сделать. Например: \"Вася, добавь две колонки в базу\".\nВозникает парадоксальная ситуация, чем более технически подкован заказчик тем, как правило,\nон больше пытается продавливать конкретные решения, вместо того, чтобы описывать свою\nбизнес-задачу (цель), оставляя вам манёвр для решения.\n\nИзбежать этого невозможно, никто и никогда не будет давать идеальных задач, которые\nсозданы исходя из бизнес-целей. Такое, конечно же, бывает, но гораздо реже, чем вам\nможет показаться. В итоге бизнес-аналитикой занимается разработчик (кроме сложных случаев),\nи это нормально. Докопавшись до сути, может оказаться так, что кода писать не надо вообще\nи достаточно поменять правила игры.\n\nДальше по курсу мы будем исходить из того, что все цели уже определены и нужно именно\nписать код, но перед тем, как мы двинемся дальше, я расскажу о том, как смотреть\nна мир глазами бизнеса и почему это полезно.\n\nПодумайте вот о чём. Откуда бизнес узнает, что нужно делать? Работая на дядю может сложиться\nвпечатление, что там наверху умные люди, которые знают, что делают. На самом деле они не знают.\nПредставьте, что вы начинаете с нуля свой стартап. После непродолжительного анализа станет\nпонятно, что основная сложность не в том, чтобы понять \"что делать\", а в том, чтобы понять\n\"что не делать\". На эту тему есть обязательная книга к прочтению, которая поменяет\nваше мировоззрение: \"Бизнес с нуля. Метод Lean Startup.\"\n\n## Lean Startup\n\n\n\nНе обращайте внимание на слово \"стартап\" в заголовке, эта методология одинаково хорошо работает\nи для больших бизнесов и для молодых проектов. Удивительно, но основная идея этого подхода\nпришла из научного мира и называется \"научный метод\":\n\n```\nНау́чный ме́тод — совокупность основных способов получения новых знаний и методов решения\nзадач в рамках любой науки.\n\nМетод включает в себя способы исследования феноменов, систематизацию, корректировку новых\nи полученных ранее знаний. Умозаключения и выводы делаются с помощью правил и принципов\nрассуждения на основе эмпирических (наблюдаемых и измеряемых) данных об объекте. Базой\nполучения данных являются наблюдения и эксперименты. Для объяснения наблюдаемых фактов\nвыдвигаются гипотезы и строятся теории, на основании которых в свою очередь строится\nматематическое описание — модель изучаемого объекта.\n```\n\nПервое. Логика контринтуитивна. Понять, что нужно вашим пользователям заранее и без общения\nс ними, практически невозможно. Используя lean startup мы выдвигаем гипотезы, а не\nпродумываем конкретные решения. Пример гипотез:\n\n```\nПользователи хотят заказывать такси без необходимости звонить оператору и диктовать адрес.\n\nПользователю удобнее оплачивать такси с карты, чем наличными\n```\n\nПроницательный читатель увидит, что при таком подходе, нет цели реализовать сразу всё, от и\nдо продумав все части программы. Задачей станет реализовать только то, что может помочь\nподтвердить или опровергнуть гипотезу. Ведь если гипотеза не верна, это автоматически означает,\nчто нужно корректировать все дальнейшие планы. В противном случае будут большие потери.\n\nПосле того, как гипотеза готова, делается всё необходимое для её проверки. Многие гипотезы,\nпо факту, не требуют написания кода вообще. Например, гипотеза про удобство оплаты такси\nкартой проверяется звонками друзьям/постами в соцсети. Согласитесь, что это сильно дешевле,\nпроще и быстрее, чем месяцами писать приложение, а потом увидеть, что это никому не нужно.\n\nНа выходе получается цепочка: Гипотеза -> Реализация (если нужно) -> Анализ данных. Повторяя\nэту цепочку снова и снова, мы получаем продукт, который действительно работает и отвечает\nбизнес-целям.\n\nКлючевые слова для самообразования:\n\n* Customer development\n* Business Model Canvas\n* Minimum Viable Product\n* Pivot\n\n## SMART\n\nКогда речь идёт про уже существующий бизнес или, даже, личные цели, то подойдёт такой\nподход как [SMART](https://ru.wikipedia.org/wiki/SMART):\n\n```\nЭто мнемоническая аббревиатура, используемая в менеджменте и проектном управлении для\nопределения целей и постановки задач:\n\n* конкретный (specific);\n* измеримый (measurable);\n* достижимый (attainable);\n* значимый (relevant);\n* соотносимый с конкретным сроком (time-bounded)\n```\n\nЭтот подход хорошо расписан в вики, поэтому не буду заниматься копипастой.\n\n## Impact mapping\n\n\n\nImpact Mapping простая и эффективная техника для определения целей заказчика\nи передача этих целей разработчикам.\n\nImpact Mapping — это диаграмма связей (mind map) по целям проекта с картой влияний, которые должны\nподтолкнуть бизнес заказчика к достижению целей.\n\n### Why?\n\nЦентральный элемент нашей карты, который отвечает на ключевой вопрос:\nЗачем мы это делаем? Это цель, которую бизнес пытается достичь.\n\n### Who?\n\nНа первом уровне мы отвечаем на вопросы: Кто поможет достичь желаемого результата?\nКто может помешать? Кто пользователи нашего продукта? Сюда войдут все заинтересованные стороны, которые могут повлиять на цели бизнеса.\n\n### How?\n\nНа втором уровне мы должны описать воздействия, которые должны оказать заинтересованные\nстороны, чтобы бизнес достиг целей. Мы ищем ответ на вопросы: Как они помогут бизнесу\nдостичь целей? Как они могут помешать успеху проекта?\n\n### What?\n\nПосле ответа на основные вопросы можно обсудить конкретные задачи. Третий уровень\nотвечает на вопросы: Что мы можем сделать как организация или команда разработки,\nчтобы создать необходимые воздействия? Здесь будет описан конечный результат нашей работы.\n\nПодробнее об этом подходе можно прочитать в\n[замечательной статье](https://habrahabr.ru/post/246401/) Александра Бындю на Хабре.\n\n## User Story Mapping\n\n\n\nПосле определения карты влияний на цели можно определить роли пользователей,\nкак они будут взаимодействовать с системой, важность задач, план релизов и т.д.\n\nЦель `user story mapping` в том, чтобы приоритезировать пользовательские истории\nпо важности.\n\nПример пользовательской истории:\n\n```\nЯ, как менеджер по продажам, хочу видеть отчёт по интересам клиентов в курсах, для того,\nчтобы принять решение о создании нового курса и приглашения этих клиентов принять в нём участие.\n```\n\nОб этой полезной технике можно найти много статей на просторах сети. Подробнее\nна ней останавливаться не будем, пора переходить к самому курсу).\n\n\n## Проект: Электронная продажа билетов\n\n\n\nНа протяжении курса мы будем создавать систему для продажи билетов в кинотеатре\nчерез интернет. Бизнес-анализ тоже будет присутствовать, но в очень ограниченном\nварианте. Основной упор на то, как писать код.\n\n## Основные темы\n\nПо пути разберём много страшных слов, и я понимаю, что многие вещи, о которых будет говориться,\nвызовут ещё больше вопросов, чем ответов. Цель этого курса показать новые горизонты,\nа не дать всеобъемлющее руководство к действию. Этим курсом ваш путь только начинается.\n\n* Domain-Driven Design\n* Entity, Value-Object\n* Repository\n* Service Layer\n* Inversion Of Control\n* Dependency Inversion Principle\n* Dependency Injection Container\n* FSM\n\n## Дополнительные темы\n\nВ процессе используем множество разных библиотек, таких как:\n\n* bottlejs\n* uuid/validate.js\n* lodash/date-fns\n"},"id":139,"slug":"js-ddd","challenges_count":3,"name":"JS: Предметно-ориентированное проектирование","allow_indexing":true,"state":"approved","course_state":"finished","pricing_type":"paid","description":"На этом курсе вы изучите предметно-ориентированное программирование. Вы узнаете больше об инверсии зависимостей и репозиториях. В итоге научитесь использовать шаблон Service Layer для разделения кода на слои. Знания из этого курса помогают программистам выделять правильные сущности и находить связи между ними.","kind":"advanced","updated_at":"2026-01-20T11:54:39.971Z","language":"javascript","duration_cache":30060,"skills":["Использовать предметно-ориентированный дизайн в своей повседневной практике","Грамотно переносить логику предметной области на код (сущности, сервисы)","Правильно строить архитектуру сложных бизнес-приложений, разделять код на слои в соответствии с шаблоном Service Layer","По максимуму использовать возможности ООП для организации легко расширяемого и тестируемого кода"],"keywords":["сущности","сервисы","репозитории","валидация","инверсия зависимостей"],"lessons_count":8,"cover":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6OTEzMiwicHVyIjoiYmxvYl9pZCJ9fQ==--1b8ef92e1ca01464452e31b4419760772ddac0c9/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJqcGciLCJyZXNpemVfdG9fZmlsbCI6WzYwMCw0MDBdfSwicHVyIjoidmFyaWF0aW9uIn19--39ba06fa99226096df9fc6bb31f84e1d29ea98e9/image.png"},"recommendedLandings":[{"stack":{"id":71,"slug":"js-domain-driven-design","title":"DDD на Javascript","audience":"for_programmers","start_type":"anytime","pricing_model":"subscription","priority":"medium","kind":"track","state":"published","stack_state":"finished","order":4700,"duration_in_months":2},"id":127,"slug":"js-domain-driven-design","title":"DDD на Javascript","subtitle":"Навык ООП и предметно-ориентированного программирования для создания масштабируемого кода и карьерного роста","subtitle_for_lists":"Изучите ООП и DDD для создания масштабируемого кода","locale":"ru","current":true,"duration_in_months_text":"2 месяца","stack_slug":"js-domain-driven-design","price_text":"от 3 900 ₽","duration_text":"2 месяца","cover_list_variant":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDAwNywicHVyIjoiYmxvYl9pZCJ9fQ==--f0b38f0e25ed59255acec6eaeaeec0a99aec453f/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Binary%20code-rafiki.png"}],"lessonMemberUnit":null,"accessToLearnUnitExists":false,"accessToCourseExists":false},"url":"/courses/js-ddd/lessons/intro/theory_unit","version":"8f286f6358a90a7bef2263b3a6edf5a90a94fa42","encryptHistory":false,"clearHistory":false}"><style data-mantine-styles="true">:root, :host{--mantine-font-family: Arial, sans-serif;--mantine-font-family-headings: Arial, sans-serif;--mantine-heading-font-weight: normal;--mantine-radius-default: 0rem;--mantine-primary-color-filled: var(--mantine-color-indigo-filled);--mantine-primary-color-filled-hover: var(--mantine-color-indigo-filled-hover);--mantine-primary-color-light: var(--mantine-color-indigo-light);--mantine-primary-color-light-hover: var(--mantine-color-indigo-light-hover);--mantine-primary-color-light-color: var(--mantine-color-indigo-light-color);--mantine-spacing-xxl: calc(4rem * var(--mantine-scale));--mantine-font-size-xs: 12px;--mantine-font-size-sm: 14px;--mantine-font-size-md: 16px;--mantine-font-size-lg: clamp(16.0000px, calc(15.2727px + 0.2273vw), 18.0000px);--mantine-font-size-xl: clamp(16.0000px, calc(14.5455px + 0.4545vw), 20.0000px);--mantine-font-size-display-3: clamp(32.0000px, calc(26.1818px + 1.8182vw), 48.0000px);--mantine-font-size-display-2: clamp(36.0000px, calc(25.8182px + 3.1818vw), 64.0000px);--mantine-font-size-display-1: clamp(40.0000px, calc(25.4545px + 4.5455vw), 80.0000px);--mantine-font-size-h1: clamp(28.0000px, calc(23.6364px + 1.3636vw), 40.0000px);--mantine-font-size-h2: clamp(24.0000px, calc(21.0909px + 0.9091vw), 32.0000px);--mantine-font-size-h3: clamp(20.0000px, calc(17.0909px + 0.9091vw), 28.0000px);--mantine-font-size-h4: clamp(16.0000px, calc(13.0909px + 0.9091vw), 24.0000px);--mantine-font-size-h5: clamp(16.0000px, calc(14.5455px + 0.4545vw), 20.0000px);--mantine-font-size-h6: 1rem;--mantine-primary-color-0: var(--mantine-color-indigo-0);--mantine-primary-color-1: var(--mantine-color-indigo-1);--mantine-primary-color-2: var(--mantine-color-indigo-2);--mantine-primary-color-3: var(--mantine-color-indigo-3);--mantine-primary-color-4: var(--mantine-color-indigo-4);--mantine-primary-color-5: var(--mantine-color-indigo-5);--mantine-primary-color-6: var(--mantine-color-indigo-6);--mantine-primary-color-7: var(--mantine-color-indigo-7);--mantine-primary-color-8: var(--mantine-color-indigo-8);--mantine-primary-color-9: var(--mantine-color-indigo-9);--mantine-color-red-0: #ffeaea;--mantine-color-red-1: #fed4d4;--mantine-color-red-2: #f4a7a8;--mantine-color-red-3: #ec7878;--mantine-color-red-4: #e55050;--mantine-color-red-5: #e03131;--mantine-color-red-6: #e02829;--mantine-color-red-7: #c71a1c;--mantine-color-red-8: #b21218;--mantine-color-red-9: #9c0411;--mantine-color-violet-0: #fce9ff;--mantine-color-violet-1: #f1cfff;--mantine-color-violet-2: #e09bff;--mantine-color-violet-3: #d16fff;--mantine-color-violet-4: #be37fe;--mantine-color-violet-5: #b51afe;--mantine-color-violet-6: #b009ff;--mantine-color-violet-7: #9b00e4;--mantine-color-violet-8: #8a00cc;--mantine-color-violet-9: #7800b3;--mantine-color-indigo-0: #edecff;--mantine-color-indigo-1: #d6d5fe;--mantine-color-indigo-2: #aaa9f4;--mantine-color-indigo-3: #7b79eb;--mantine-color-indigo-4: #5451e4;--mantine-color-indigo-5: #3b37e0;--mantine-color-indigo-6: #2d2adf;--mantine-color-indigo-7: #1f1ec7;--mantine-color-indigo-8: #1819b2;--mantine-color-indigo-9: #0c149e;--mantine-color-cyan-0: #dffdff;--mantine-color-cyan-1: #caf5ff;--mantine-color-cyan-2: #99e8ff;--mantine-color-cyan-3: #64daff;--mantine-color-cyan-4: #3ccffe;--mantine-color-cyan-5: #24c8fe;--mantine-color-cyan-6: #00c2ff;--mantine-color-cyan-7: #00ade4;--mantine-color-cyan-8: #009acd;--mantine-color-cyan-9: #0085b5;--mantine-color-green-0: #e9fdec;--mantine-color-green-1: #d7f6dc;--mantine-color-green-2: #b0eab9;--mantine-color-green-3: #86df94;--mantine-color-green-4: #62d574;--mantine-color-green-5: #4ccf5f;--mantine-color-green-6: #3fcc54;--mantine-color-green-7: #2fb344;--mantine-color-green-8: #25a03b;--mantine-color-green-9: #138a2e;--mantine-color-yellow-0: #fff7e2;--mantine-color-yellow-1: #ffeecd;--mantine-color-yellow-2: #ffdc9c;--mantine-color-yellow-3: #ffc966;--mantine-color-yellow-4: #feb93a;--mantine-color-yellow-5: #feae1e;--mantine-color-yellow-6: #ffa90f;--mantine-color-yellow-8: #ca8200;--mantine-color-yellow-9: #af7000;--mantine-h1-font-size: clamp(28.0000px, calc(23.6364px + 1.3636vw), 40.0000px);--mantine-h1-font-weight: normal;--mantine-h2-font-size: clamp(24.0000px, calc(21.0909px + 0.9091vw), 32.0000px);--mantine-h2-font-weight: normal;--mantine-h3-font-size: clamp(20.0000px, calc(17.0909px + 0.9091vw), 28.0000px);--mantine-h3-font-weight: normal;--mantine-h4-font-size: clamp(16.0000px, calc(13.0909px + 0.9091vw), 24.0000px);--mantine-h4-font-weight: normal;--mantine-h5-font-size: clamp(16.0000px, calc(14.5455px + 0.4545vw), 20.0000px);--mantine-h5-font-weight: normal;--mantine-h6-font-size: 1rem;--mantine-h6-font-weight: normal;}
:root[data-mantine-color-scheme="dark"], :host([data-mantine-color-scheme="dark"]){--mantine-color-anchor: var(--mantine-color-text);--mantine-color-dimmed: #495057;--mantine-color-dark-filled: var(--mantine-color-dark-5);--mantine-color-dark-filled-hover: var(--mantine-color-dark-6);--mantine-color-dark-light: rgba(105, 105, 105, 0.15);--mantine-color-dark-light-hover: rgba(105, 105, 105, 0.2);--mantine-color-dark-light-color: var(--mantine-color-dark-0);--mantine-color-dark-outline: var(--mantine-color-dark-1);--mantine-color-dark-outline-hover: rgba(184, 184, 184, 0.05);--mantine-color-gray-filled: var(--mantine-color-gray-5);--mantine-color-gray-filled-hover: var(--mantine-color-gray-6);--mantine-color-gray-light: rgba(222, 226, 230, 0.15);--mantine-color-gray-light-hover: rgba(222, 226, 230, 0.2);--mantine-color-gray-light-color: var(--mantine-color-gray-0);--mantine-color-gray-outline: var(--mantine-color-gray-1);--mantine-color-gray-outline-hover: rgba(241, 243, 245, 0.05);--mantine-color-red-filled: var(--mantine-color-red-5);--mantine-color-red-filled-hover: var(--mantine-color-red-6);--mantine-color-red-light: rgba(236, 120, 120, 0.15);--mantine-color-red-light-hover: rgba(236, 120, 120, 0.2);--mantine-color-red-light-color: var(--mantine-color-red-0);--mantine-color-red-outline: var(--mantine-color-red-1);--mantine-color-red-outline-hover: rgba(254, 212, 212, 0.05);--mantine-color-pink-filled: var(--mantine-color-pink-5);--mantine-color-pink-filled-hover: var(--mantine-color-pink-6);--mantine-color-pink-light: rgba(250, 162, 193, 0.15);--mantine-color-pink-light-hover: rgba(250, 162, 193, 0.2);--mantine-color-pink-light-color: var(--mantine-color-pink-0);--mantine-color-pink-outline: var(--mantine-color-pink-1);--mantine-color-pink-outline-hover: rgba(255, 222, 235, 0.05);--mantine-color-grape-filled: var(--mantine-color-grape-5);--mantine-color-grape-filled-hover: var(--mantine-color-grape-6);--mantine-color-grape-light: rgba(229, 153, 247, 0.15);--mantine-color-grape-light-hover: rgba(229, 153, 247, 0.2);--mantine-color-grape-light-color: var(--mantine-color-grape-0);--mantine-color-grape-outline: var(--mantine-color-grape-1);--mantine-color-grape-outline-hover: rgba(243, 217, 250, 0.05);--mantine-color-violet-filled: var(--mantine-color-violet-5);--mantine-color-violet-filled-hover: var(--mantine-color-violet-6);--mantine-color-violet-light: rgba(209, 111, 255, 0.15);--mantine-color-violet-light-hover: rgba(209, 111, 255, 0.2);--mantine-color-violet-light-color: var(--mantine-color-violet-0);--mantine-color-violet-outline: var(--mantine-color-violet-1);--mantine-color-violet-outline-hover: rgba(241, 207, 255, 0.05);--mantine-color-indigo-filled: var(--mantine-color-indigo-5);--mantine-color-indigo-filled-hover: var(--mantine-color-indigo-6);--mantine-color-indigo-light: rgba(123, 121, 235, 0.15);--mantine-color-indigo-light-hover: rgba(123, 121, 235, 0.2);--mantine-color-indigo-light-color: var(--mantine-color-indigo-0);--mantine-color-indigo-outline: var(--mantine-color-indigo-1);--mantine-color-indigo-outline-hover: rgba(214, 213, 254, 0.05);--mantine-color-blue-filled: var(--mantine-color-blue-5);--mantine-color-blue-filled-hover: var(--mantine-color-blue-6);--mantine-color-blue-light: rgba(116, 192, 252, 0.15);--mantine-color-blue-light-hover: rgba(116, 192, 252, 0.2);--mantine-color-blue-light-color: var(--mantine-color-blue-0);--mantine-color-blue-outline: var(--mantine-color-blue-1);--mantine-color-blue-outline-hover: rgba(208, 235, 255, 0.05);--mantine-color-cyan-filled: var(--mantine-color-cyan-5);--mantine-color-cyan-filled-hover: var(--mantine-color-cyan-6);--mantine-color-cyan-light: rgba(100, 218, 255, 0.15);--mantine-color-cyan-light-hover: rgba(100, 218, 255, 0.2);--mantine-color-cyan-light-color: var(--mantine-color-cyan-0);--mantine-color-cyan-outline: var(--mantine-color-cyan-1);--mantine-color-cyan-outline-hover: rgba(202, 245, 255, 0.05);--mantine-color-teal-filled: var(--mantine-color-teal-5);--mantine-color-teal-filled-hover: var(--mantine-color-teal-6);--mantine-color-teal-light: rgba(99, 230, 190, 0.15);--mantine-color-teal-light-hover: rgba(99, 230, 190, 0.2);--mantine-color-teal-light-color: var(--mantine-color-teal-0);--mantine-color-teal-outline: var(--mantine-color-teal-1);--mantine-color-teal-outline-hover: rgba(195, 250, 232, 0.05);--mantine-color-green-filled: var(--mantine-color-green-5);--mantine-color-green-filled-hover: var(--mantine-color-green-6);--mantine-color-green-light: rgba(134, 223, 148, 0.15);--mantine-color-green-light-hover: rgba(134, 223, 148, 0.2);--mantine-color-green-light-color: var(--mantine-color-green-0);--mantine-color-green-outline: var(--mantine-color-green-1);--mantine-color-green-outline-hover: rgba(215, 246, 220, 0.05);--mantine-color-lime-filled: var(--mantine-color-lime-5);--mantine-color-lime-filled-hover: var(--mantine-color-lime-6);--mantine-color-lime-light: rgba(192, 235, 117, 0.15);--mantine-color-lime-light-hover: rgba(192, 235, 117, 0.2);--mantine-color-lime-light-color: var(--mantine-color-lime-0);--mantine-color-lime-outline: var(--mantine-color-lime-1);--mantine-color-lime-outline-hover: rgba(233, 250, 200, 0.05);--mantine-color-yellow-filled: var(--mantine-color-yellow-5);--mantine-color-yellow-filled-hover: var(--mantine-color-yellow-6);--mantine-color-yellow-light: rgba(255, 201, 102, 0.15);--mantine-color-yellow-light-hover: rgba(255, 201, 102, 0.2);--mantine-color-yellow-light-color: var(--mantine-color-yellow-0);--mantine-color-yellow-outline: var(--mantine-color-yellow-1);--mantine-color-yellow-outline-hover: rgba(255, 238, 205, 0.05);--mantine-color-orange-filled: var(--mantine-color-orange-5);--mantine-color-orange-filled-hover: var(--mantine-color-orange-6);--mantine-color-orange-light: rgba(255, 192, 120, 0.15);--mantine-color-orange-light-hover: rgba(255, 192, 120, 0.2);--mantine-color-orange-light-color: var(--mantine-color-orange-0);--mantine-color-orange-outline: var(--mantine-color-orange-1);--mantine-color-orange-outline-hover: rgba(255, 232, 204, 0.05);--app-cta-gradient: linear-gradient(90deg, var(--mantine-color-blue-9) 0%, var(--mantine-color-cyan-7) 100%);--app-color-surface: #2e2e2e;}
:root[data-mantine-color-scheme="light"], :host([data-mantine-color-scheme="light"]){--mantine-color-anchor: var(--mantine-color-text);--mantine-color-dimmed: #495057;--mantine-color-red-light: rgba(224, 40, 41, 0.1);--mantine-color-red-light-hover: rgba(224, 40, 41, 0.12);--mantine-color-red-outline-hover: rgba(224, 40, 41, 0.05);--mantine-color-violet-light: rgba(176, 9, 255, 0.1);--mantine-color-violet-light-hover: rgba(176, 9, 255, 0.12);--mantine-color-violet-outline-hover: rgba(176, 9, 255, 0.05);--mantine-color-indigo-light: rgba(45, 42, 223, 0.1);--mantine-color-indigo-light-hover: rgba(45, 42, 223, 0.12);--mantine-color-indigo-outline-hover: rgba(45, 42, 223, 0.05);--mantine-color-cyan-light: rgba(0, 194, 255, 0.1);--mantine-color-cyan-light-hover: rgba(0, 194, 255, 0.12);--mantine-color-cyan-outline-hover: rgba(0, 194, 255, 0.05);--mantine-color-green-light: rgba(63, 204, 84, 0.1);--mantine-color-green-light-hover: rgba(63, 204, 84, 0.12);--mantine-color-green-outline-hover: rgba(63, 204, 84, 0.05);--mantine-color-yellow-light: rgba(255, 169, 15, 0.1);--mantine-color-yellow-light-hover: rgba(255, 169, 15, 0.12);--mantine-color-yellow-outline-hover: rgba(255, 169, 15, 0.05);--app-color-surface: #f1f3f5;--app-cta-gradient: linear-gradient(90deg, var(--mantine-color-blue-filled) 0%, var(--mantine-color-cyan-5) 100%);}</style><style data-mantine-styles="classes">@media (max-width: 35.99375em) {.mantine-visible-from-xs {display: none !important;}}@media (min-width: 36em) {.mantine-hidden-from-xs {display: none !important;}}@media (max-width: 47.99375em) {.mantine-visible-from-sm {display: none !important;}}@media (min-width: 48em) {.mantine-hidden-from-sm {display: none !important;}}@media (max-width: 61.99375em) {.mantine-visible-from-md {display: none !important;}}@media (min-width: 62em) {.mantine-hidden-from-md {display: none !important;}}@media (max-width: 74.99375em) {.mantine-visible-from-lg {display: none !important;}}@media (min-width: 75em) {.mantine-hidden-from-lg {display: none !important;}}@media (max-width: 87.99375em) {.mantine-visible-from-xl {display: none !important;}}@media (min-width: 88em) {.mantine-hidden-from-xl {display: none !important;}}</style><div style="position:absolute;top:0rem" class=""></div><div style="max-width:var(--container-size-xl);height:100%;min-height:0rem" class=""><style data-mantine-styles="inline">.__m__-_R_5ub_{--grid-gutter:0rem;}</style><div style="height:100%;min-height:0rem" class="m_410352e9 mantine-Grid-root __m__-_R_5ub_"><div class="m_dee7bd2f mantine-Grid-inner" style="height:100%"><style data-mantine-styles="inline">.__m__-_R_rdub_{--col-flex-grow:auto;--col-flex-basis:91.66666666666667%;--col-max-width:91.66666666666667%;}@media(min-width: 48em){.__m__-_R_rdub_{--col-flex-grow:auto;--col-flex-basis:83.33333333333334%;--col-max-width:83.33333333333334%;}}</style><div style="min-width:0rem;height:100%;min-height:0rem;display:flex" class="m_96bdd299 mantine-Grid-col __m__-_R_rdub_"><style data-mantine-styles="inline">.__m__-_R_6qrdub_{margin-top:0rem;padding-inline:var(--mantine-spacing-xs);width:100%;}@media(min-width: 48em){.__m__-_R_6qrdub_{margin-top:var(--mantine-spacing-xl);width:80%;}}@media(min-width: 62em){.__m__-_R_6qrdub_{padding-inline:var(--mantine-spacing-xl);}}</style><div style="margin-inline:auto;max-width:var(--mantine-breakpoint-xl)" class="__m__-_R_6qrdub_"><div style="color:var(--mantine-color-dimmed)" class="m_4451eb3a mantine-Center-root" data-inline="true"><div style="--ti-size:var(--ti-size-xs);--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;margin-inline-end:calc(0.125rem * var(--mantine-scale));color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent" data-size="xs"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-lock "><path d="M5 13a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v6a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-6"></path><path d="M11 16a1 1 0 1 0 2 0a1 1 0 0 0 -2 0"></path><path d="M8 11v-4a4 4 0 1 1 8 0v4"></path></svg></div><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">JS: Предметно-ориентированное проектирование</p></div><h1 style="--title-fw:var(--mantine-h1-font-weight);--title-lh:var(--mantine-h1-line-height);--title-fz:var(--mantine-h1-font-size);margin-bottom:var(--mantine-spacing-xl)" class="m_8a5d1357 mantine-Title-root" data-order="1">Теория: Введение</h1><script type="application/ld+json">{"@context":"https://schema.org","@type":"LearningResource","name":"Введение","inLanguage":"ru","isPartOf":{"@type":"LearningResource","name":"JS: Предметно-ориентированное проектирование"},"isAccessibleForFree":"False","hasPart":{"@type":"WebPageElement","isAccessibleForFree":"False","cssSelector":".paywalled"}}</script><div class=""><div style="--alert-color:var(--mantine-color-indigo-light-color);margin-bottom:var(--mantine-spacing-lg);font-size:var(--mantine-font-size-lg)" class="m_66836ed3 mantine-Alert-root" id="mantine-_R_remqrdub_" role="alert" aria-describedby="mantine-_R_remqrdub_-body" aria-labelledby="mantine-_R_remqrdub_-title"><div class="m_a5d60502 mantine-Alert-wrapper"><div class="m_667f2a6a mantine-Alert-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-rocket "><path d="M4 13a8 8 0 0 1 7 7a6 6 0 0 0 3 -5a9 9 0 0 0 6 -8a3 3 0 0 0 -3 -3a9 9 0 0 0 -8 6a6 6 0 0 0 -5 3"></path><path d="M7 14a6 6 0 0 0 -3 6a6 6 0 0 0 6 -3"></path><path d="M14 9a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"></path></svg></div><div class="m_667c2793 mantine-Alert-body"><div class="m_6a03f287 mantine-Alert-title"><span id="mantine-_R_remqrdub_-title" class="m_698f4f23 mantine-Alert-label">Полный доступ к материалам</span></div><div id="mantine-_R_remqrdub_-body" class="m_7fa78076 mantine-Alert-message"><div style="--group-gap:var(--mantine-spacing-md);--group-align:center;--group-justify:space-between;--group-wrap:wrap" class="m_4081bf90 mantine-Group-root"><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Зарегистрируйтесь и получите доступ к этому и десяткам других курсов</p><a style="--button-height:var(--button-height-xs);--button-padding-x:var(--button-padding-x-xs);--button-fz:var(--mantine-font-size-xs);--button-bg:linear-gradient(45deg, var(--mantine-color-blue-filled) 0%, var(--mantine-color-cyan-filled) 100%);--button-hover:linear-gradient(45deg, var(--mantine-color-blue-filled) 0%, var(--mantine-color-cyan-filled) 100%);--button-color:var(--mantine-color-white);--button-bd:none" class="mantine-focus-auto mantine-active m_77c9d27d mantine-Button-root m_87cf2631 mantine-UnstyledButton-root" data-variant="gradient" data-size="xs" href="/u/new"><span class="m_80f1301b mantine-Button-inner"><span class="m_811560b9 mantine-Button-label">Зарегистрироваться</span></span></a></div></div></div></div></div><div class="paywalled m_d08caa0 mantine-Typography-root"><p>Обычно во вступлении мы рассказываем то, что ожидает вас внутри курса, но здесь я решил
рассказать кое-что важное. Попробуйте самостоятельно ответить на вопрос. Какая основная
задача программиста?</p>
<p>Вероятно, вы ответите "писать код" и будете не правы. Писать код это всего лишь средство,
причём не единственное. Также часто решением задачи является удаление кода или, вообще,
отсутствие кода, и всё это тоже область компетенции программиста.</p>
<p>Начать нужно с того, что программирование, как таковое, это не цель, это всего лишь
средство достижения бизнес-целей той компании, которая вас нанимает. В конечном итоге
всё программное обеспечение так или иначе служит удовлетворению потребностей бизнеса:
увеличению прибыли, снижению издержек. <a style="text-decoration:underline" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="https://ru.hexlet.io/blog/posts/developers-business-value" rel="noopener noreferrer" target="_blank">Хорошая статья об этом</a> есть в нашем блоге.</p>
<p>На практике это означает очень простую вещь, перед тем как бросаться писать код,
нужно понять цель того, что вам нужно сделать. Хочу ещё раз акцентировать ваше внимание, на том,
что цель это <strong>зачем</strong> мы это делаем, а не <strong>что</strong> нужно сделать. У меня
есть хорошая аналогия, которую мы постоянно наблюдаем в своей жизни. Вспомните приходы
к доктору. Многие люди пытаются рассказывать доктору не только симптомы, но и
выдвигают гипотезы, а некоторые прямо утверждают, что у них конкретная болезнь и, более того,
они знают, как лечиться. Доктора обычно пропускают это мимо ушей, потому что его
задача понять истинную причину. То же самое часто происходит в разработке. К вам приходит
заказчик и говорит, <strong>что</strong> нужно сделать. Например: "Вася, добавь две колонки в базу".
Возникает парадоксальная ситуация, чем более технически подкован заказчик тем, как правило,
он больше пытается продавливать конкретные решения, вместо того, чтобы описывать свою
бизнес-задачу (цель), оставляя вам манёвр для решения.</p>
<p>Избежать этого невозможно, никто и никогда не будет давать идеальных задач, которые
созданы исходя из бизнес-целей. Такое, конечно же, бывает, но гораздо реже, чем вам
может показаться. В итоге бизнес-аналитикой занимается разработчик (кроме сложных случаев),
и это нормально. Докопавшись до сути, может оказаться так, что кода писать не надо вообще
и достаточно поменять правила игры.</p>
<p>Дальше по курсу мы будем исходить из того, что все цели уже определены и нужно именно
писать код, но перед тем, как мы двинемся дальше, я расскажу о том, как смотреть
на мир глазами бизнеса и почему это полезно.</p>
<p>Подумайте вот о чём. Откуда бизнес узнает, что нужно делать? Работая на дядю может сложиться
впечатление, что там наверху умные люди, которые знают, что делают. На самом деле они не знают.
Представьте, что вы начинаете с нуля свой стартап. После непродолжительного анализа станет
понятно, что основная сложность не в том, чтобы понять "что делать", а в том, чтобы понять
"что не делать". На эту тему есть обязательная книга к прочтению, которая поменяет
ваше мировоззрение: "Бизнес с нуля. Метод Lean Startup."</p>
<h2 id="heading-2-1">Lean Startup</h2>
<p><img style="--image-object-fit:contain;width:auto" class="m_9e117634 mantine-Image-root" src="/rails/active_storage/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6OTEzMywicHVyIjoiYmxvYl9pZCJ9fQ==--2524e1bcc3508f57d84476898b65576d078ea57d/lean-startup.jpg" alt="lean startup" loading="lazy"/></p>
<p>Не обращайте внимание на слово "стартап" в заголовке, эта методология одинаково хорошо работает
и для больших бизнесов и для молодых проектов. Удивительно, но основная идея этого подхода
пришла из научного мира и называется "научный метод":</p>
<code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">Нау́чный ме́тод — совокупность основных способов получения новых знаний и методов решения
задач в рамках любой науки.
Метод включает в себя способы исследования феноменов, систематизацию, корректировку новых
и полученных ранее знаний. Умозаключения и выводы делаются с помощью правил и принципов
рассуждения на основе эмпирических (наблюдаемых и измеряемых) данных об объекте. Базой
получения данных являются наблюдения и эксперименты. Для объяснения наблюдаемых фактов
выдвигаются гипотезы и строятся теории, на основании которых в свою очередь строится
математическое описание — модель изучаемого объекта.</code>
<p>Первое. Логика контринтуитивна. Понять, что нужно вашим пользователям заранее и без общения
с ними, практически невозможно. Используя lean startup мы выдвигаем гипотезы, а не
продумываем конкретные решения. Пример гипотез:</p>
<code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">Пользователи хотят заказывать такси без необходимости звонить оператору и диктовать адрес.
Пользователю удобнее оплачивать такси с карты, чем наличными</code>
<p>Проницательный читатель увидит, что при таком подходе, нет цели реализовать сразу всё, от и
до продумав все части программы. Задачей станет реализовать только то, что может помочь
подтвердить или опровергнуть гипотезу. Ведь если гипотеза не верна, это автоматически означает,
что нужно корректировать все дальнейшие планы. В противном случае будут большие потери.</p>
<p>После того, как гипотеза готова, делается всё необходимое для её проверки. Многие гипотезы,
по факту, не требуют написания кода вообще. Например, гипотеза про удобство оплаты такси
картой проверяется звонками друзьям/постами в соцсети. Согласитесь, что это сильно дешевле,
проще и быстрее, чем месяцами писать приложение, а потом увидеть, что это никому не нужно.</p>
<p>На выходе получается цепочка: Гипотеза -> Реализация (если нужно) -> Анализ данных. Повторяя
эту цепочку снова и снова, мы получаем продукт, который действительно работает и отвечает
бизнес-целям.</p>
<p>Ключевые слова для самообразования:</p>
<ul>
<li>Customer development</li>
<li>Business Model Canvas</li>
<li>Minimum Viable Product</li>
<li>Pivot</li>
</ul>
<h2 id="heading-2-2">SMART</h2>
<p>Когда речь идёт про уже существующий бизнес или, даже, личные цели, то подойдёт такой
подход как <a style="text-decoration:underline" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="https://ru.wikipedia.org/wiki/SMART" rel="noopener noreferrer" target="_blank">SMART</a>:</p>
<code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">Это мнемоническая аббревиатура, используемая в менеджменте и проектном управлении для
определения целей и постановки задач:
* конкретный (specific);
* измеримый (measurable);
* достижимый (attainable);
* значимый (relevant);
* соотносимый с конкретным сроком (time-bounded)</code>
<p>Этот подход хорошо расписан в вики, поэтому не буду заниматься копипастой.</p>
<h2 id="heading-2-3">Impact mapping</h2>
<p><img style="--image-object-fit:contain;width:auto" class="m_9e117634 mantine-Image-root" src="/rails/active_storage/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6OTEzNCwicHVyIjoiYmxvYl9pZCJ9fQ==--0b21fb9cc6a81cfc0e0dac27c1fd18606264ef16/impact-mapping.png" alt="impact mapping" loading="lazy"/></p>
<p>Impact Mapping простая и эффективная техника для определения целей заказчика
и передача этих целей разработчикам.</p>
<p>Impact Mapping — это диаграмма связей (mind map) по целям проекта с картой влияний, которые должны
подтолкнуть бизнес заказчика к достижению целей.</p>
<h3 id="heading-3-4">Why?</h3>
<p>Центральный элемент нашей карты, который отвечает на ключевой вопрос:
Зачем мы это делаем? Это цель, которую бизнес пытается достичь.</p>
<h3 id="heading-3-5">Who?</h3>
<p>На первом уровне мы отвечаем на вопросы: Кто поможет достичь желаемого результата?
Кто может помешать? Кто пользователи нашего продукта? Сюда войдут все заинтересованные стороны, которые могут повлиять на цели бизнеса.</p>
<h3 id="heading-3-6">How?</h3>
<p>На втором уровне мы должны описать воздействия, которые должны оказать заинтересованные
стороны, чтобы бизнес достиг целей. Мы ищем ответ на вопросы: Как они помогут бизнесу
достичь целей? Как они могут помешать успеху проекта?</p>
<h3 id="heading-3-7">What?</h3>
<p>После ответа на основные вопросы можно обсудить конкретные задачи. Третий уровень
отвечает на вопросы: Что мы можем сделать как организация или команда разработки,
чтобы создать необходимые воздействия? Здесь будет описан конечный результат нашей работы.</p>
<p>Подробнее об этом подходе можно прочитать в
<a style="text-decoration:underline" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="https://habrahabr.ru/post/246401/" rel="noopener noreferrer" target="_blank">замечательной статье</a> Александра Бындю на Хабре.</p>
<h2 id="heading-2-8">User Story Mapping</h2>
<p><img style="--image-object-fit:contain;width:auto" class="m_9e117634 mantine-Image-root" src="/rails/active_storage/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6OTEzNSwicHVyIjoiYmxvYl9pZCJ9fQ==--f42628aac813fc6f8f59e0fe4a80efcf90f2934c/user-story-mapping.png" alt="user impact mapping" loading="lazy"/></p>
<p>После определения карты влияний на цели можно определить роли пользователей,
как они будут взаимодействовать с системой, важность задач, план релизов и т.д.</p>
<p>Цель <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">user story mapping</code> в том, чтобы приоритезировать пользовательские истории
по важности.</p>
<p>Пример пользовательской истории:</p>
<code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">Я, как менеджер по продажам, хочу видеть отчёт по интересам клиентов в курсах, для того,
чтобы принять решение о создании нового курса и приглашения этих клиентов принять в нём участие.</code>
<p>Об этой полезной технике можно найти много статей на просторах сети. Подробнее
на ней останавливаться не будем, пора переходить к самому курсу).</p>
<h2 id="heading-2-9">Проект: Электронная продажа билетов</h2>
<p><img style="--image-object-fit:contain;width:auto" class="m_9e117634 mantine-Image-root" src="/rails/active_storage/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6OTEzNiwicHVyIjoiYmxvYl9pZCJ9fQ==--b9e9c7bb075e7ec5e72dd78b6919259167bf9699/cinema.jpg" alt="cinema" loading="lazy"/></p>
<p>На протяжении курса мы будем создавать систему для продажи билетов в кинотеатре
через интернет. Бизнес-анализ тоже будет присутствовать, но в очень ограниченном
варианте. Основной упор на то, как писать код.</p>
<h2 id="heading-2-10">Основные темы</h2>
<p>По пути разберём много страшных слов, и я понимаю, что многие вещи, о которых будет говориться,
вызовут ещё больше вопросов, чем ответов. Цель этого курса показать новые горизонты,
а не дать всеобъемлющее руководство к действию. Этим курсом ваш путь только начинается.</p>
<ul>
<li>Domain-Driven Design</li>
<li>Entity, Value-Object</li>
<li>Repository</li>
<li>Service Layer</li>
<li>Inversion Of Control</li>
<li>Dependency Inversion Principle</li>
<li>Dependency Injection Container</li>
<li>FSM</li>
</ul>
<h2 id="heading-2-11">Дополнительные темы</h2>
<p>В процессе используем множество разных библиотек, таких как:</p>
<ul>
<li>bottlejs</li>
<li>uuid/validate.js</li>
<li>lodash/date-fns</li>
</ul></div><div style="margin-block:var(--mantine-spacing-xl)" class=""><h2 style="--title-fw:var(--mantine-h2-font-weight);--title-lh:var(--mantine-h2-line-height);--title-fz:var(--mantine-h2-font-size);margin-bottom:var(--mantine-spacing-md)" class="m_8a5d1357 mantine-Title-root" data-order="2">Рекомендуемые программы</h2><style data-mantine-styles="inline">.__m__-_R_2mremqrdub_{--carousel-slide-gap:var(--mantine-spacing-xs);--carousel-slide-size:70%;}@media(min-width: 36em){.__m__-_R_2mremqrdub_{--carousel-slide-gap:var(--mantine-spacing-xl);--carousel-slide-size:50%;}}</style><div style="--carousel-control-size:calc(2.5rem * var(--mantine-scale));--carousel-controls-offset:var(--mantine-spacing-sm);margin-bottom:var(--mantine-spacing-lg);padding-block:var(--mantine-spacing-sm);background:var(--app-color-surface)" class="m_17884d0f mantine-Carousel-root responsiveClassName" data-orientation="horizontal" data-include-gap-in-size="true"><div class="m_39bc3463 mantine-Carousel-controls" data-orientation="horizontal"><button class="mantine-focus-auto m_64f58e10 mantine-Carousel-control m_87cf2631 mantine-UnstyledButton-root" type="button" data-inactive="true" data-type="previous" tabindex="-1"><svg viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg" style="transform:rotate(90deg);width:calc(1rem * var(--mantine-scale));height:calc(1rem * var(--mantine-scale));display:block"><path d="M3.13523 6.15803C3.3241 5.95657 3.64052 5.94637 3.84197 6.13523L7.5 9.56464L11.158 6.13523C11.3595 5.94637 11.6759 5.95657 11.8648 6.15803C12.0536 6.35949 12.0434 6.67591 11.842 6.86477L7.84197 10.6148C7.64964 10.7951 7.35036 10.7951 7.15803 10.6148L3.15803 6.86477C2.95657 6.67591 2.94637 6.35949 3.13523 6.15803Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg></button><button class="mantine-focus-auto m_64f58e10 mantine-Carousel-control m_87cf2631 mantine-UnstyledButton-root" type="button" data-inactive="true" data-type="next" tabindex="-1"><svg viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg" style="transform:rotate(-90deg);width:calc(1rem * var(--mantine-scale));height:calc(1rem * var(--mantine-scale));display:block"><path d="M3.13523 6.15803C3.3241 5.95657 3.64052 5.94637 3.84197 6.13523L7.5 9.56464L11.158 6.13523C11.3595 5.94637 11.6759 5.95657 11.8648 6.15803C12.0536 6.35949 12.0434 6.67591 11.842 6.86477L7.84197 10.6148C7.64964 10.7951 7.35036 10.7951 7.15803 10.6148L3.15803 6.86477C2.95657 6.67591 2.94637 6.35949 3.13523 6.15803Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg></button></div><div class="m_a2dae653 mantine-Carousel-viewport" data-type="media"><div class="m_fcd81474 mantine-Carousel-container __m__-_R_2mremqrdub_" data-orientation="horizontal"><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/programs/js-domain-driven-design?promo_name=programs_list&promo_position=course&promo_creative=catalog_card&promo_type=card" target="_blank"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><div style="--group-gap:calc(0.25rem * var(--mantine-scale));--group-align:center;--group-justify:flex-start;--group-wrap:nowrap" class="m_4081bf90 mantine-Group-root"><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">2 месяца</span><span class="mantine-focus-auto m_b6d8b162 mantine-Text-root">·</span><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Для продвинутых</span></div><p style="margin-bottom:var(--mantine-spacing-sm);font-size:var(--mantine-font-size-h5);font-weight:bold" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">DDD на Javascript</p><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Изучите ООП и DDD для создания масштабируемого кода</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDAwNywicHVyIjoiYmxvYl9pZCJ9fQ==--f0b38f0e25ed59255acec6eaeaeec0a99aec453f/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Binary%20code-rafiki.png" alt="DDD на Javascript" loading="eager"/></div><div style="--group-gap:var(--mantine-spacing-md);--group-align:end;--group-justify:space-between;--group-wrap:wrap;margin-top:var(--mantine-spacing-xs)" class="m_4081bf90 mantine-Group-root"><p style="font-size:var(--mantine-font-size-xl)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">от 3 900 ₽</p><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Посмотреть →</p></div></div></div></a></div></div><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/courses?promo_name=programs_list&promo_position=course&promo_creative=catalog_card&promo_type=card"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><h2 style="--title-fw:var(--mantine-h2-font-weight);--title-lh:var(--mantine-h2-line-height);--title-fz:var(--mantine-h2-font-size);margin-bottom:var(--mantine-spacing-md);font-size:var(--mantine-font-size-h3)" class="m_8a5d1357 mantine-Title-root" data-order="2" data-responsive="true">Каталог</h2><p style="margin-bottom:auto" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Полный список доступных курсов по разным направлениям</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="/vite/assets/development-BVihs_d5.png" alt="Orientation"/></div></div></div></a></div></div></div></div></div></div></div></div></div><style data-mantine-styles="inline">.__m__-_R_1bdub_{--col-flex-grow:auto;--col-flex-basis:8.333333333333334%;--col-max-width:8.333333333333334%;}@media(min-width: 48em){.__m__-_R_1bdub_{--col-flex-grow:auto;--col-flex-basis:16.666666666666668%;--col-max-width:16.666666666666668%;}}</style><div style="min-width:0rem;height:100%;min-height:0rem" class="m_96bdd299 mantine-Grid-col __m__-_R_1bdub_"><div style="margin-inline:var(--mantine-spacing-xs)" class="mantine-visible-from-sm"><a style="--button-color:var(--mantine-color-white);margin-bottom:var(--mantine-spacing-lg);text-decoration:none" class="mantine-focus-auto m_849cf0da mantine-focus-auto m_77c9d27d mantine-Button-root m_87cf2631 mantine-UnstyledButton-root m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/courses/js-ddd/lessons/intro/finish_unit?unit=theory" data-disabled="true" data-block="true" disabled=""><span class="m_80f1301b mantine-Button-inner"><span class="m_811560b9 mantine-Button-label"><span style="margin-inline-end:var(--mantine-spacing-xs)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Дальше</span>→</span></span></a><a style="padding-inline:0rem" class="mantine-focus-auto m_f0824112 mantine-NavLink-root m_87cf2631 mantine-UnstyledButton-root"><span class="m_690090b5 mantine-NavLink-section" data-position="left"><div style="--ti-size:var(--ti-size-sm);--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent" data-size="sm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-list-numbers "><path d="M11 6h9"></path><path d="M11 12h9"></path><path d="M12 18h8"></path><path d="M4 16a2 2 0 1 1 4 0c0 .591 -.5 1 -1 1.5l-3 2.5h4"></path><path d="M6 10v-6l-2 2"></path></svg></div></span><div class="m_f07af9d2 mantine-NavLink-body"><span class="m_1f6ac4c4 mantine-NavLink-label">Навигация по теме</span><span class="m_57492dcc mantine-NavLink-description">Теория</span></div><span class="m_690090b5 mantine-NavLink-section" data-position="right"></span></a><div style="margin-block:var(--mantine-spacing-lg)" class="m_3eebeb36 mantine-Divider-root" data-orientation="horizontal" role="separator"></div><div style="margin-block:var(--mantine-spacing-lg)" class=""><div style="justify-content:space-between;margin-bottom:calc(0.1875rem * var(--mantine-scale));color:var(--mantine-color-dimmed);font-size:var(--mantine-font-size-xs)" class="m_8bffd616 mantine-Flex-root __m__-_R_qimrbdub_"><p style="font-size:var(--mantine-font-size-xs)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Завершено</p><p style="font-size:var(--mantine-font-size-xs)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">0 / 8</p></div><div style="--progress-size:var(--progress-size-sm)" class="m_db6d6462 mantine-Progress-root" data-size="sm"><div style="--progress-section-size:0%;--progress-section-color:var(--mantine-color-gray-filled)" class="m_2242eb65 mantine-Progress-section" role="progressbar" aria-valuemax="100" aria-valuemin="0" aria-valuenow="0" aria-valuetext="0%"></div></div></div><button style="padding-inline:0rem" class="mantine-focus-auto m_f0824112 mantine-NavLink-root m_87cf2631 mantine-UnstyledButton-root" type="button"><span class="m_690090b5 mantine-NavLink-section" data-position="left"><div style="--ti-size:var(--ti-size-sm);--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent" data-size="sm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-message "><path d="M8 9h8"></path><path d="M8 13h6"></path><path d="M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3h12"></path></svg></div></span><div class="m_f07af9d2 mantine-NavLink-body"><span class="m_1f6ac4c4 mantine-NavLink-label">Обсуждения (архив)</span><span class="m_57492dcc mantine-NavLink-description"></span></div></button><div style="--toc-bg:var(--mantine-color-blue-light);--toc-color:var(--mantine-color-blue-light-color);--toc-size:var(--mantine-font-size-sm);--toc-radius:var(--mantine-radius-sm);margin-top:var(--mantine-spacing-xl)" class="m_bcaa9990 mantine-TableOfContents-root" data-variant="light" data-size="sm"></div></div><div class="mantine-hidden-from-sm"><div style="--stack-gap:0rem;--stack-align:stretch;--stack-justify:flex-start" class="m_6d731127 mantine-Stack-root"><a style="--button-color:var(--mantine-color-white);margin-bottom:var(--mantine-spacing-xs);padding:0rem;text-decoration:none" class="mantine-focus-auto m_849cf0da mantine-focus-auto m_77c9d27d mantine-Button-root m_87cf2631 mantine-UnstyledButton-root m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/courses/js-ddd/lessons/intro/finish_unit?unit=theory" data-disabled="true" data-block="true" disabled=""><span class="m_80f1301b mantine-Button-inner"><span class="m_811560b9 mantine-Button-label">→</span></span></a><button style="--ai-size:var(--ai-size-sm);--ai-bg:transparent;--ai-hover:var(--mantine-color-indigo-light-hover);--ai-color:var(--mantine-color-indigo-light-color);--ai-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;padding-block:var(--mantine-spacing-lg);color:inherit;width:100%" class="mantine-focus-auto m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="subtle" data-size="sm" data-disabled="true" type="button" disabled=""><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-list-numbers "><path d="M11 6h9"></path><path d="M11 12h9"></path><path d="M12 18h8"></path><path d="M4 16a2 2 0 1 1 4 0c0 .591 -.5 1 -1 1.5l-3 2.5h4"></path><path d="M6 10v-6l-2 2"></path></svg></span></button><button style="--ai-size:var(--ai-size-sm);--ai-bg:transparent;--ai-hover:var(--mantine-color-indigo-light-hover);--ai-color:var(--mantine-color-indigo-light-color);--ai-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;padding-block:var(--mantine-spacing-lg);color:inherit;width:100%" class="mantine-focus-auto mantine-active m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="subtle" data-size="sm" type="button"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-message "><path d="M8 9h8"></path><path d="M8 13h6"></path><path d="M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3h12"></path></svg></span></button></div></div></div></div></div></div></div>
</main>
<footer class="bg-dark fw-light text-light px-3 py-5">
<div class="row small">
<div class="col-12 col-sm-6 col-md-3">
<div class="h5 mb-3">Хекслет</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/about">О нас</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/testimonials">Отзывы</a>
</li>
<li>
<span class="nav-link link-light py-1 ps-0 external-link" data-href="https://b2b.hexlet.io" role="button">Корпоративное обучение</span>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/blog">Блог</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/qna">Вопросы и ответы</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/glossary">Глоссарий</a>
</li>
<li>
<span class="nav-link link-light py-1 ps-0 external-link" data-href="https://help.hexlet.io" data-target="_blank" role="button">Справка</span>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" target="_blank" rel="noopener noreferrer" href="/map">Карта сайта</a>
</li>
</ul>
</div>
<div class="col-12 col-sm-6 col-md-3">
<div class="h5 fw-normal mb-3">Направления</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_devops">DevOps
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_data_analytics">Аналитика
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_backend_development">Бэкенд
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_programming">Программирование
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_testing">Тестирование
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_front_end_dev">Фронтенд
</a></li>
</ul>
</div>
<div class="col-12 col-sm-6 col-md-3">
<div class="h5">Профессии</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/devops-engineer-from-scratch">DevOps-инженер с нуля</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/go">Go-разработчик</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/java">Java-разработчик</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/python">Python-разработчик </a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/data-analytics">Аналитик данных</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/qa-engineer">Инженер по ручному тестированию</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/php">РНР-разработчик</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/frontend">Фронтенд-разработчик</a>
</li>
</ul>
</div>
<div class="col-12 col-sm-6 col-md-3">
<div class="h5">Навыки</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/python-django-developer">Django</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/docker">Docker</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/php-laravel-developer">Laravel</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/postman">Postman</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/js-react-developer">React</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/js-rest-api">REST API в Node.js</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/spring-boot">Spring Boot</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/typescript">Typescript</a>
</li>
</ul>
</div>
</div>
<hr>
<div class="row">
<div class="col-12 col-sm-4 col-md-2">
<div class="fs-4">
<ul class="list-unstyled d-flex">
<li class="me-3">
<a aria-label="Telegram" target="_blank" class="link-light" rel="noopener noreferrer nofollow" href="https://t.me/hexlet_ru"><span class="bi bi-telegram"></span>
</a></li>
<li>
<a aria-label="Youtube" target="_blank" class="link-light" rel="noopener noreferrer nofollow" href="https://www.youtube.com/user/HexletUniversity"><span class="bi bi-youtube"></span>
</a></li>
</ul>
</div>
<div class="mb-2 d-flex flex-column">
<a class="link-light text-decoration-none" rel="nofollow" href="mailto:support@hexlet.io">support@hexlet.io</a>
<a class="link-light text-decoration-none py-2" target="_blank" href="https://t.me/hexlet_help_bot">t.me/hexlet_help_bot</a>
</div>
<ul class="list-unstyled d-flex">
<li class="me-3">
<span class="link-light text-decoration-none opacity-50 x-font-size-18 external-link" rel="nofollow" data-href="https://hexlet.io/locale/switch?new_locale=en" data-target="_self" role="button"><span class="my-auto">EN</span>
</span></li>
<li class="me-3">
<span class="link-light text-decoration-none opacity-50 x-font-size-18 opacity-100 external-link" rel="nofollow" data-href="https://ru.hexlet.io/locale/switch?new_locale=ru" data-target="_self" role="button"><span class="my-auto">RU</span>
</span></li>
<li class="me-3">
<span class="link-light text-decoration-none opacity-50 x-font-size-18 external-link" rel="nofollow" data-href="https://kz.hexlet.io/locale/switch?new_locale=kz" data-target="_self" role="button"><span class="my-auto">KZ</span>
</span></li>
</ul>
</div>
<div class="col-12 col-sm-4 col-md-3">
<ul class="list-unstyled fs-4">
<li class="mb-3">
<a class="link-light text-decoration-none" href="tel:8%20800%20100%2022%2047">8 800 100 22 47</a>
<span class="d-block opacity-50 small">бесплатно по РФ</span>
</li>
<li>
<a class="link-light text-decoration-none" href="tel:%2B7%20495%20085%2021%2062">+7 495 085 21 62</a>
<span class="d-block opacity-50 small">бесплатно по Москве</span>
</li>
</ul>
</div>
<div class="col-12 col-sm-4 col-md-3">
<div class="small mb-3">Образовательные услуги оказываются на основании Л035-01298-77/01989008 от 14.03.2025</div>
<ul class="list-unstyled small">
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/legal">Правовая информация</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/offer">Оферта</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/license">Лицензия</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/contacts">Контакты</a>
</li>
</ul>
</div>
<div class="col-12 col-sm-12 col-md-4 small">
<div class="mb-2">
<div>ООО «<a href="/" class="text-decoration-none link-light">Хекслет Рус</a>»</div>
<div>108813 г. Москва, вн.тер.г. поселение Московский,</div>
<div>г. Московский, ул. Солнечная, д. 3А, стр. 1, помещ. 20Б/3</div>
<div>ОГРН 1217300010476</div>
<div>ИНН 7325174845</div>
</div>
<hr>
<div>АНО ДПО «<a href="/" class="text-decoration-none link-light">Учебный центр «Хекслет</a>»</div>
<div>119331 г. Москва, вн. тер. г. муниципальный округ</div>
<div>Ломоносовский, пр-кт Вернадского, д. 29</div>
<div>ОГРН 1247700712390</div>
<div>ИНН 7736364948</div>
</div>
</div>
</footer>
<div id="root-assistant-offcanvas"></div>
<script src="/vite/assets/assistant-Bukl1lYy.js" crossorigin="anonymous" type="module"></script><link rel="modulepreload" href="/vite/assets/chunk-DsPFFUou.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/init-BrRXra1y.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/ErrorFallbackBlock-naDSYSy9.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/MarkdownBlock-DbyKWoR_.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/gon-D3e4yh1x.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/mantine-CGMYrt2Y.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/shiki-V011pkdv.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/utils-DRqSHbQE.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/routes-CCH8ilKF.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/lib-XR8Qr8kR.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/dist-GCHh59xr.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Box-B5-OOzBf.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/notifications.store-C-3AFSMn.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/useIsomorphicEffect-HJ6VK0D3.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/lib-KSp6QbZ0.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/axios-BEvgo0ym.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/classnames-l6ipYlLR.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/dayjs.min-BkKovM-s.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/debounce-jMQ_Cf4f.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/i18next-BlSq9s7B.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/client-U9M77rxp.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-dom-DaLxUz_h.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/useTranslation-Bx1Cdrkz.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/compiler-runtime-6XxiPFnt.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/jsx-runtime-CwjcCKJi.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-CkL4ZRHB.js" as="script" crossorigin="anonymous">
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v67327c56f0bb4ef8b305cae61679db8f1769101564043" integrity="sha512-rdcWY47ByXd76cbCFzznIcEaCN71jqkWBBqlwhF1SY7KubdLKZiEGeP7AyieKZlGP9hbY/MhGrwXzJC/HulNyg==" data-cf-beacon='{"version":"2024.11.0","token":"d11015b65d11429ea6b4a2ef37dd7e0b","server_timing":{"name":{"cfCacheStatus":true,"cfEdge":true,"cfExtPri":true,"cfL4":true,"cfOrigin":true,"cfSpeedBrain":true},"location_startswith":null}}' crossorigin="anonymous"></script>
</body>
</html>