Как да научим софтуерния дизайн и архитектура - пътна карта

Тази статия е обобщение на това, за което пиша в най-новия си проект, solidbook.io - Наръчникът за софтуерно проектиране и архитектура с TypeScript. Вижте го, харесва ли ви тази публикация.

За мен е лудост да разглеждам факта, че Facebook някога е бил празен текстов файл на нечий компютър.

Lol.

През изминалата година усилено се занимавах със софтуерния дизайн и архитектура, управляван от домейн дизайн и написах книга по него и исках да отделя малко време, за да се опитам да го наредя в нещо полезно, което бих могъл да споделя с общността .

Ето моята пътна карта за това как да науча софтуерния дизайн и архитектура.

Разбих го на два артефакта: стека и картата .

Стека

Подобно на модела OSI в мрежата, всеки слой се изгражда върху основата на предишния.

Стека

Картата

Въпреки че мисля, че стекът е добър, за да се види по-общата картина на това как всичко работи заедно, картата е малко по-подробна (и вдъхновена от пътната карта на уеб разработчика) и в резултат на това мисля, че е по-полезна.

Ето го отдолу! За да разклоните репото, прочетете подробното ми описание и го изтеглете във висока резолюция, щракнете тук.

Пътна карта за софтуерен дизайн и архитектура

Етап 1: Чист код

Първата стъпка към създаването на дълготраен софтуер е да разберем как да напишем чист код .

Чистият код е код, който е лесен за разбиране и промяна. На ниско ниво това се проявява в няколко избора на дизайн като:

  • като е последователен
  • предпочитайки смислени имена на променливи, методи и класове пред писане на коментари
  • гарантиране, че кодът е отстъпен и разположен правилно
  • гарантира, че всички тестове могат да се изпълняват
  • писане на чисти функции без странични ефекти
  • не преминавайки null

Писането на чист код е изключително важно.

Помислете за това като игра на дженга.

За да поддържаме структурата на нашия проект стабилна във времето, неща като отстъпи, малки класове и методи и смислени имена се отплащат много в дългосрочен план.

Най-добрият ресурс да научите как да пишете чист код е книгата на чичо Боб „Чист код“.

Етап 2: Програмиране на парадигми

Сега, когато пишем четим код, който е лесен за поддръжка, би било добра идея наистина да разберем 3-те основни програмни парадигми и начина, по който те влияят върху начина, по който пишем кода.

В книгата на чичо Боб "Чиста архитектура" той обръща внимание на факта, че:

  • Обектно-ориентираното програмиране е инструментът, най-подходящ за определяне на начина, по който пресичаме архитектурните граници с полиморпизъм и приставки
  • Функционалното програмиране е инструментът, който използваме, за да изтласкаме данните до границите на нашите приложения
  • и Структурираното програмиране е инструментът, който използваме за писане на алгоритми

Това предполага, че ефективният софтуер използва хибридни всички 3 стила на парадигми за програмиране по различно време.

Въпреки че можете да възприемете строго функционален или строго обектно-ориентиран подход към писането на код, разбирането къде всеки превъзхожда ще подобри качеството на вашите проекти.

Ако всичко, което имате, е чук, всичко изглежда като пирон.

Ресурси

За функционално програмиране вижте:

  • Предимно адекватното ръководство на професор Фризби за функционално програмиране
  • Моделиране на домейни, направено функционално

Етап 3: Обектно-ориентирано програмиране

Важно е да знаете как работи всяка от парадигмите и как те ви подтикват да структурирате кода в тях, но по отношение на архитектурата, обектно-ориентираното програмиране е ясният инструмент за работата .

Обектно-ориентираното програмиране не само ни позволява да създадем архитектура на приставки и да вградим гъвкавост в нашите проекти; OOP идва с 4-те принципа на OOP (капсулиране, наследяване, полиморфизъм и абстракция), които ни помагат да създадем богати модели на домейни .

Повечето разработчици, изучаващи обектно-ориентирано програмиране, никога не стигат до тази част: научават се как да създават софтуерна реализация на проблемния домейн и го намират в центъра на слоесто уеб приложение.

Функционалното програмиране може да изглежда като средство за всички цели в този сценарий, но бих препоръчал да се запознаете с дизайн, управляван от модели и дизайн, управляван от домейни, за да разберете по-голямата картина за това как обектните моделиращи могат да капсулират цял ​​бизнес в модел на домейн с нулева зависимост.

Защо това е огромна сделка?

Това е огромно, защото ако можете да създадете умствен модел на бизнес, можете да създадете софтуерна реализация на този бизнес.

Етап 4: Принципи на проектиране

На този етап разбирате, че обектно-ориентираното програмиране е много полезно за капсулиране на богати модели на домейни и решаване на третия тип „Проблеми с твърдия софтуер“ - сложни домейни.

Но ООП може да въведе някои предизвикателства пред дизайна.

Кога трябва да използвам състав?

Кога трябва да използвам наследство?

Кога трябва да използвам абстрактен клас?

Принципите на проектиране са наистина добре установени и проверени в битки обектно-ориентирани най-добри практики, които използвате като парапети.

Някои примери за общи принципи на проектиране, с които трябва да се запознаете, са:

  • Състав върху наследяването
  • Капсулирайте това, което варира
  • Програма срещу абстракции, а не конкременти
  • Принципът на Холивуд: "Не ни се обаждайте, ние ще ви се обаждаме"
  • ТВЪРДИТЕ принципи, особено принципа на единната отговорност
  • СУХО (Не се повтаряйте)
  • ЯГНИ (няма да ти трябва)

Не забравяйте да стигнете до собствените си заключения. Не просто следвайте това, което някой друг казва, че трябва да направите. Уверете се, че има смисъл за вас.

Етап 5: Дизайнерски модели

Почти всеки проблем в софтуера вече е категоризиран и решен. Ние наричаме тези модели: дизайнерски модели, всъщност.

Има 3 категории дизайнерски модели: творчески , структурни и поведение .

Творчески

Творческите модели са модели, които контролират начина на създаване на обектите.

Примери за творчески модели включват:

  • Моделът Singleton , за да се гарантира, че може да съществува само един екземпляр на клас
  • Най- абстрактна фабрика , за създаване на копие на няколко семейства от класа
  • В схемата прототип , за започване с пример, който се клонира от съществуващ

Структурни

Структурните модели са модели, които опростяват начина, по който определяме връзките между компонентите.

Примери за структурни дизайнерски модели включват:

  • В модела адаптер , за създаване на интерфейс да се даде възможност класове, които обикновено не могат да работят заедно, за да работят заедно.
  • Моделът Bridge , за разделяне на клас, който всъщност трябва да бъде един или повече, в набор от класове, които принадлежат към йерархия, позволявайки внедряванията да се разработват независимо един от друг.
  • Моделът на декоратора , за динамично добавяне на отговорности към обекти.

Поведенчески

Моделите на поведение са често срещани модели за улесняване на елегантната комуникация между обектите.

Примери за поведенчески модели са:

  • В схемата за шаблони , за отлагане на точните стъпки на алгоритъм за подклас.
  • Моделът на посредника за определяне на точните комуникационни канали, разрешени между класовете.
  • Моделът Observer , за да позволи на класовете да се абонират за нещо, което представлява интерес, и да бъдат уведомени, когато настъпи промяна.

Критика на дизайнерския модел

Дизайнерските модели са страхотни и всички, но понякога те могат да дадат допълнителна сложност на нашите дизайни. Важно е да запомните YAGNI и да се опитате да улесним дизайна си възможно най-лесно. Използвайте дизайнерски модели само когато сте наистина сигурни, че имате нужда от тях. Ще разберете кога ще го направите.

Ако знаем какви са всеки от тези модели, кога да ги използваме и кога дори не си правим труда да ги използваме, ние сме в добра форма, за да започнем да разбираме как да създаваме по-големи системи.

Причината за това е, че архитектурните модели са просто дизайнерски модели, раздути в мащаб до високо ниво , където дизайнерските модели са реализации на ниско ниво (по-близо до класове и функции).

Ресурси

Гуру за рефакторинг - дизайнерски модели

Етап 6: Архитектурни принципи

Сега сме на по-високо ниво на мислене отвъд нивото на класа.

Сега разбираме, че решенията, които вземаме за организиране и изграждане на взаимоотношения между компонентите на високо и ниско ниво, ще окажат значително въздействие върху поддържаемостта, гъвкавостта и проверимостта на нашия проект.

Научете ръководните принципи, които ви помагат да изградите гъвкавостта, от която се нуждае вашата кодова база, за да можете да реагирате на нови функции и изисквания с възможно най-малко усилия.

Ето какво бих препоръчал да научите веднага:

  • Принципи на проектиране на компоненти: Принцип на стабилна абстракция, Принцип на стабилна зависимост и Принцип на ациклична зависимост, за това как да организирате компонентите, техните зависимости, кога да ги свържете и последиците от случайно създаване на цикли на зависимост и разчитане на нестабилни компоненти.
  • Политика срещу подробности, за да разберете как да разделите правилата на вашето приложение от подробностите за изпълнението.
  • Граници и как да идентифицирате поддомените, в които се намират функциите на вашето приложение.

Чичо Боб откри и първоначално документира много от тези принципи, така че най-добрият ресурс да научите за това отново е „Чиста архитектура“.

Етап 7: Архитектурни стилове

Архитектурата е свързана с нещата, които имат значение.

Става въпрос за идентифициране на това, от което се нуждае една система, за да бъде успешна, и след това за подреждане на шансовете за успех, като изберете архитектурата, която най-добре отговаря на изискванията.

Например, система, която има много сложност на бизнес логиката, би се възползвала от използването на слоеста архитектура за капсулиране на тази сложност.

Система като Uber трябва да може да обработва много събития в реално време наведнъж и да актуализира местоположенията на драйверите, така че архитектурата на стила публикуване-абониране може да бъде най-ефективна.

Ще се повторя тук, защото е важно да се отбележи, че 3-те категории архитектурни стилове са подобни на 3-те категории дизайнерски модели, тъй като архитектурните стилове са дизайнерски модели на високо ниво .

Структурни

Проекти с различни нива на компоненти и широка функционалност ще се възползват или ще страдат от приемането на структурна архитектура.

Ето няколко примера:

  • Базираните на компоненти архитектури подчертават разделянето на проблемите между отделните компоненти в системата. Помислете за Google за секунда. Помислете колко приложения имат в рамките на своето предприятие (Google Docs, Google Drive, Google Maps и т.н.). За платформи с много функционалности, базирани на компоненти архитектури разделят проблемите на свободно свързани независими компоненти. Това е хоризонтално разделяне.
  • Монолитен означава, че приложението се комбинира в една платформа или програма, въведени изцяло. Забележка: Можете да имате базирана на компоненти И монолитна архитектура, ако разделяте правилно приложенията си, но все пак разполагате всичко като едно цяло .
  • Многослойните архитектури разделят опасенията вертикално, като изрязват софтуера на инфраструктура, приложения и домейн слоеве.

Чиста архитектура

Пример за вертикално намаляване на проблемите на дадено приложение чрез използване на слоеста архитектура. Прочетете тук за повече информация как да направите това.

Съобщения

В зависимост от вашия проект, съобщенията може да са наистина важен компонент за успеха на системата. За проекти като този архитектурите, базирани на съобщения, надграждат принципите на функционалното програмиране и модели на поведенчески дизайн като модела на наблюдателя.

Ето няколко примера за базирани на съобщения архитектурни стилове:

  • Управлявани от събития архитектури разглеждат всички значими промени в състоянието като събития. Например, в рамките на приложение за търговия с винил, състоянието на офертата може да се промени от „изчакващо“ на „прието“, когато двете страни се споразумеят за сделката.
  • Архитектурите за публикуване-абониране се основават на шаблона за дизайн на Observer, като го правят основният метод за комуникация между самата система, крайни потребители / клиенти и други системи и компоненти.

Разпределени

Разпределената архитектура просто означава, че компонентите на системата са разположени поотделно и работят чрез комуникация по мрежов протокол. Разпределените системи могат да бъдат много ефективни за мащабиране на производителността, мащабиране на екипи и делегиране (потенциално скъпи задачи или) отговорност на други компоненти.

Няколко примера за разпределени архитектурни стилове са:

  • Архитектура клиент-сървър . Една от най-често срещаните архитектури, при която разделяме работата, която трябва да свършим, между клиента (презентация) и сървъра (бизнес логика).
  • Peer-to-peer архитектурите разпределят задачи от приложния слой между еднакво привилегировани участници, образувайки peer-to-peer мрежа.

Етап 8: Архитектурни модели

Архитектурните модели обясняват с по-големи тактически подробности как всъщност да се изпълни един от тези архитектурни стилове .

Ето няколко примера за архитектурни модели и стилове, които те наследяват:

  • Domain-Driven Design е подход към разработването на софтуер срещу наистина сложни проблемни домейни. За да бъде DDD най-успешен, трябва да внедрим слоеста архитектура, за да отделим проблемите на даден модел от инфраструктурните детайли, които правят приложението действително да се изпълнява, като бази данни, уеб сървъри, кешове и т.н.
  • Model-View Controller е може би най-известният архитектурен модел за разработване на приложения, базирани на потребителски интерфейс. Той работи, като разделя приложението на 3 компонента: модел, изглед и контролер. MVC е невероятно полезен, когато започвате за първи път, и ви помага да се свържете с други архитектури, но има един момент, когато осъзнаем, че MVC не е достатъчен за проблеми с много бизнес логика.
  • Източникът на събития е функционален подход, при който съхраняваме само транзакциите, а никога държавата. Ако някога имаме нужда от държавата, можем да приложим всички транзакции от началото на времето.

Етап 9: Предприятия модели

Всеки архитектурен модел, който изберете, ще представи редица конструкции и технически жаргон, с които да се запознаете и да решите дали си струва усилието да се използва или не.

Като пример, че много от нас знаят, в MVC , на мнение, притежава всички слой кода за представяне на контролера е превежда команди и заявки от гледката на искания, които се разглеждат от модела и върнати от контролера .

Къде в модела (M) се справяме с тези неща ?:

  • логика за валидиране
  • инвариантни правила
  • домейн събития
  • случаи на употреба
  • сложни заявки
  • и бизнес логика

Ако просто използваме ORM (обектно-релационен картограф) като Sequelize или TypeORM като модел , всички тези важни неща, които трябва да оставим на интерпретацията къде трябва да отидем, и се оказва в някакъв неуточнен слой между (какво трябва да бъде богат ) модел и контролера .

mvc-2

Взето от „3.1 - Тънки (без логика) модели“ в solidbook.io.

Ако има нещо, което съм научил досега по време на пътуването си, надхвърляйки MVC, това е, че има конструкция за всичко .

За всяко от тези неща, които MVC не успява да адресира, съществуват други корпоративни модели, които да ги решат. Например:

  • Обектите описват модели, които имат идентичност.
  • Обектите на стойност са модели, които нямат идентичност и могат да бъдат използвани, за да капсулират логиката за проверка.
  • Събития в домейна са събития, които означават някакво релевантно бизнес събитие и могат да бъдат абонирани от други компоненти.

В зависимост от архитектурния стил, който сте избрали, ще има много други модели на предприятието, които да научите, за да приложите този модел до пълния му потенциал.

Интеграционни модели

След като приложението ви стартира и стартира, тъй като получавате все повече и повече потребители, може да срещнете проблеми с производителността. Извикванията на API могат да отнемат много време, сървърите може да се сринат от претоварване с заявки и т.н. За да разрешите тези проблеми, можете да прочетете за интегриране на неща като опашки за съобщения или кешове, за да подобрите производителността.

Това са може би най-предизвикателните неща: мащабиране, одити и изпълнение .

Проектирането на система за мащаб може да бъде невероятно предизвикателство. Изисква задълбочено разбиране на ограниченията на всеки компонент в архитектурата и план за действие за това как да смекчите стреса върху вашата архитектура и да продължите да обслужвате заявки в ситуации с висок трафик.

Необходимостта също така е необходимо да се провери какво се случва във вашето приложение. Големите корпоративни компании трябва да могат да извършват одити, за да идентифицират потенциални проблеми със сигурността, да разберат как потребителите използват техните приложения и да имат дневник на всичко, което някога се е случвало.

Това може да бъде предизвикателство за внедряване, но общите архитектури в крайна сметка изглеждат базирани на събития и се основават на широк спектър от концепции, принципи и практики за проектиране на софтуер и системи като Storming Storming, DDD, CQRS (сегрегация на отговор на командни заявки) и източник на събития .

Надявам се това да ви е било полезно!

Кажете ми, ако имате някакви предложения или въпроси.

Наздраве!

Разклонете го на GitHub

Прочетете книгата за софтуерния дизайн и архитектура

Прочетете записа

khalilstemmler.com - преподавам най-добри практики за TypeScript & Node.js за мащабни приложения и как да пиша гъвкав, поддържаем софтуер.