{"id":21228212,"url":"https://github.com/hexlet/patterns","last_synced_at":"2025-04-04T18:09:54.365Z","repository":{"id":42391480,"uuid":"122565211","full_name":"Hexlet/patterns","owner":"Hexlet","description":"Language agnostic patterns description","archived":false,"fork":false,"pushed_at":"2024-08-30T19:52:18.000Z","size":801,"stargazers_count":325,"open_issues_count":0,"forks_count":57,"subscribers_count":30,"default_branch":"main","last_synced_at":"2025-03-28T17:08:36.884Z","etag":null,"topics":["javascript","patterns","php","python","ruby"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Hexlet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-02-23T02:51:38.000Z","updated_at":"2025-03-13T18:06:17.000Z","dependencies_parsed_at":"2024-12-11T02:00:30.154Z","dependency_job_id":"1ebd55cb-945b-4ce5-970c-491c9fca17d6","html_url":"https://github.com/Hexlet/patterns","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hexlet%2Fpatterns","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hexlet%2Fpatterns/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hexlet%2Fpatterns/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hexlet%2Fpatterns/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Hexlet","download_url":"https://codeload.github.com/Hexlet/patterns/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247226215,"owners_count":20904465,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","patterns","php","python","ruby"],"created_at":"2024-11-20T23:15:14.321Z","updated_at":"2025-04-04T18:09:54.347Z","avatar_url":"https://github.com/Hexlet.png","language":"JavaScript","readme":"# Шаблоны проектирования\n\nСборник идиом и шаблонов проектирования с примерами на динамических языках. Основной упор делается на сути, на том, какая проблема решается. Каждый шаблон имеет множество вариантов реализации, что отражено в примерах.\n\nСтруктура репозитория устроена так, что в папке `content` содержится список папок соответствующих паттернам. Внутри `README.md` с общим описанием шаблона и папки по языкам, например, `javascript`. Внутри папки с языком снова папки. Каждая из них - реализация паттерна в конкретной ситуации или конкретным способом.\n\nВ тех ситуациях, когда надо приводить пример в общем описании, он приводится на JavaScript.\n\n### Лирика\n\nШаблон проектирования (паттерн) - подходы к решению типовых задач проектирования.\n\nРазумное использование паттернов позволяет сделать код понятным (более прямолинейная логика, меньше условных конструкций), гибким (легче расширять) и модульным (изменения в одних частях меньше влияют на изменения в других частях программы). Однако, неразумное их применение сделает код только хуже, что в реальном коде происходит крайне часто.\n\nКлючевое при работе с шаблонами - не запомнить конкретную реализацию паттерна для вашего языка, а понять проблему, в рамках которой появилось данное решение. Другими словами, нужно понимать, что паттерны - это не причина, а следствие. Классика [культа карго](https://ru.wikipedia.org/wiki/%D0%9A%D0%B0%D1%80%D0%B3%D0%BE-%D0%BA%D1%83%D0%BB%D1%8C%D1%82) выглядит так: программист смотрит на свой код и думает \"куда мне применить вот этот паттерн\".\n\nШаблоны проектирования - не законы физики, придуманные учёными в стенах университетов. Большинство шаблонов постоянно переизобретается разработчиками в разных уголках света. Причём не все из них вообще слышали словосочетание \"паттерны программирования\". Паттернов существует огромное количество и постоянно придумываются новые. Они относятся не только к коду. Например, существуют паттерны для работы с базами данных, с распределёнными системами, некоторые специфичны для конкретных языков, другие можно применять вообще почти для всего (например, фасад).\n\nМногие шаблоны проектирования (особенно из книги GoF) с технической точки зрения сводятся к полиморфизму подтипов. В результате снижается цикломатическая сложность кода и он становится проще, но при этом часто многословнее. Реализация подобных паттернов нередко приводит к идентичному коду, и у программистов возникает вопрос, а почему это два разных паттерна, если код и там и там практически одинаковый (или одинаковый)? Все дело в семантике (смысле). За каждым паттерном стоит смысл, который понимать важнее, чем запомнить диаграмму классов. К тому же данные диаграммы применимы только для тех языков, для которых их делали. В динамике всё проще.\n\nСистематизация паттернов имеет большое значение. Во-первых, это общая терминология, позволяющая значительно снизить издержки при коммуникациях. Во-вторых, паттерны позволяют \"стоять на плечах гигантов\", то есть не переизобретать колесо. К тому же не факт, что колесо будет изобретено.\n\n\u003e Плохая абстракция хуже дублирования кода\n\nНе забывайте, что не бывает бесплатного сыра. О паттернах принято говорить как об избавлении от всех проблем, но это не так. Любое архитектурное решение делает систему гибкой в одном направлении, но связывает в другом. Пока развитие кода идет в сторону гибкого направления, всё будет хорошо, но как только изменятся требования, может оказаться, что ваше решение никуда не годится. Решайте проблемы по мере их поступления, только так можно научиться чему-то. Написать хорошо заранее невозможно, это миф. Ваши главные друзья: тесты, рефлексия и непрерывный рефакторинг (небольшими шагами).\n\n#### Модульность\n\nХотя типичное определение модуля звучит как \"функциональность выделяется в модуль\", оно не отражает сути, что приводит к подмене понятий. Разбиение программы на модули не делает её модульной. Модульность в программировании - это малое количество связей между модулями и отсутствие циклов. Под циклическими связями понимается ситуация, в которой группа модулей зависит друг от друга так, что в группе не существует модуля, который не зависит от других модулей группы. Для двух модулей цикл означает то, что они зависят друг от друга и не могут существовать независимо.\n\nДовольно известный Open-closed Principle на самом деле говорит о модульности и нисколько не специфичен для ООП стиля разработки.\n\n#### Open-closed Principle\n\nПринцип открытости-закрытости говорит о том, что в хорошо спроектированной системе, расширение функциональности происходит не за счет модификации старого кода, а за счет добавления нового. Он неразрывно связан с модульностью. Модульный код соответствует идее принципа.\n\n### Ключевые понятия\n\n### Клиент\n\nВ текстах термин \"клиент\" обозначает пользователя, систему или код, которые используют то, о чём мы говорим. Например, клиент библиотеки - это код, который использует библиотеку.\n\n### Полезные ссылки\n\n* Вебинар Хекслета о паттернах - https://www.youtube.com/watch?v=wX6BBaQZpzE\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhexlet%2Fpatterns","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhexlet%2Fpatterns","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhexlet%2Fpatterns/lists"}