RSS

Комментарии

Просто в REST со стандартом проблема, его по сути нет. Есть рекомендации и устоявшаяся практика. Чем Вам Method+URL+параметр не нотация?

Потому что «нотация» GraphQL создана из рассчета, что у нас волшебный сервер, который одинаково эффективно возвращает запрошенные данные. И пофиг как там GraphQL ложится на внутреннюю предметную область, аппаратные ограничения, уже реализованные способы доступа к объектам. За исключением простых случаев, ситуация когда фронтендщики диктуют схему доступа к данным, пусть и прекрываясь технологией, черевата проблемами с производительностью и неоптимальной организацией хранения данных. Потому что для фронтендщика не будут видны под капотом ключи MySQL, лимиты на внешние апи, внутренная организация кэширования. И REST, на мой взгляд, куда лучше справляется как с учетом этих особенностей, так и защитой фронтеднщиков от этих ненужных деталей.

К тому же олновесная реализация нотации GraphQL для всех сущностей системы может стоить дорого. А реализация ограниченного подмножества будет по сути не особо отличаться от REST. Только вместо ендпоинтов для сущностей нужно будет создавать ресолверы для новых сущностей.

А вот возможность получить на сервер запрос всех полей и связанных с ними записей думаю сильно плохо скажется на его здоровье. Интересно посмотреть статистику отказа в обслуживании таких endpoint’ов.

Если пытаться на ендпоинте сделать логику выборки из базы как в авторезолверах, строящих запросы по аннотациям в ORM, то все может быть очень печально. А если сделать выборку вручную написанными запросами, созданными специально под конкретный флоу, то все может быть в разы лучше чем у GraphQL.
Просто в REST со стандартом проблема, его по сути нет. Есть рекомендации и устоявшаяся практика. Чем Вам Method+URL+параметр не нотация?

В REST вы тоже можете собирать с многих сервисов. Некоторые даже делают это в API gateway.

А вот возможность получить на сервер запрос всех полей и связанных с ними записей думаю сильно плохо скажется на его здоровье. Интересно посмотреть статистику отказа в обслуживании таких endpoint’ов.
Единая нотация

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

Возможность указания только тех полей, что нужно

В REST это тоже делалось задолго до создания GraphQL. Параметр fields в конце URL.

Можно за один запрос получить данные с разных backend-ов

Обожаю этот аргумент! Вы когда-нибудь писали кастомный резолвер, который вам соберет сложный объект по нескольким микросервисам? Это одинаковая головная боль, что для REST, что для GraphQL. Только в случае последнего вам придется писать резольвер по-настоящему общего назначения, который будет работать для всех полей и связанных объектов, и потом решать проблемы производительности с этим чудом. В случае REST такие вещи хотя бы ограничивают универсальность применения одним ендпоинтом и доступными для него спидхаками и упрощениями выборки.

Можно получать связанные данные (пользователь + его заказы, например)

Да можно, вопрос какой ценой нагрузки на сервер. Вероятно, можно написать хаки для ресольвера, чтобы он какие-то случаи запросов покрывал джойнами, а не выборкой связанных данных отдельными подзапросами. Но чем такие оптимизации принципиально отличаются от создания специализированного рестового ендпоинта?

Запросы к бекендам могут параллелиться без изменения логики в клиенте

Чтобы что?
Плюсы GraphQL:

— Единая нотация
— Возможность указания только тех полей, что нужно
— Можно за один запрос получить данные с разных backend-ов
— Можно получать связанные данные (пользователь + его заказы, например)
— Запросы к бекендам могут параллелиться без изменения логики в клиенте

Но есть и минусы:

— Секурити, точнее отсутствие
— Своя нотация запросов
— Нельзя указать * для полей — обязательно перечислять
— Скорость ниже, чем прямой вызов (но может быть быстрее за счёт параллелизма)

Вообще для UI подход GraphQL оказался очень удобным даже не смотря на минусы.
Как по мне, не увидел никаких преимуществ GraphQL, кроме возможности менять запросы на стороне клиента, не переписывая сервер. Впрочем, не такой это и плюс.

Сдается мне, это придумали фронтедщики, чтоб не пинать бэкендщиков по каждому чиху.

Вот только мне кажется при такой свободе и отсутствии кеширования такие запросы, особенно сложные, сильно просаживают быстродействие.
Что использовать в работе

Итак, REST API применяют, если:
— работают с небольшими программами, где нужно обрабатывать простые данные
— пользователи работают с ними одинаково
— нет требований к сложным запросам

GraphQL выбирают, когда:
— у серверного оборудования маленькая пропускная способность. Необходимо снизить количество ввода-вывода данных
— в одном адресе нужно объединить множество источников
— запросы пользователей различны, необходимо прорабатывать разные ответы
Что использовать в работе

Итак, REST API применяют, если:
— работают с небольшими программами, где нужно обрабатывать простые данные
— пользователи работают с ними одинаково
— нет требований к сложным запросам

GraphQL выбирают, когда:
— у серверного оборудования маленькая пропускная способность. Необходимо снизить количество ввода-вывода данных
— в одном адресе нужно объединить множество источников
— запросы пользователей различны, необходимо прорабатывать разные ответы
Что использовать в работе

Итак, REST API применяют, если:
— работают с небольшими программами, где нужно обрабатывать простые данные
— пользователи работают с ними одинаково
— нет требований к сложным запросам

GraphQL выбирают, когда:
— у серверного оборудования маленькая пропускная способность. Необходимо снизить количество ввода-вывода данных
— в одном адресе нужно объединить множество источников
— запросы пользователей различны, необходимо прорабатывать разные ответы
Основным минусом REST API считают создание множества эндпоинтов. Работать с ним — это как уточнять что-либо в разных компаниях. Нужно звонить всем по очереди.

Например, вы хотите посмотреть варианты пиццы и указываете точку /pizza. API принесёт информацию о цене, акциях и составе продукта. Но вы просили информацию о видах пиццы. Придётся постоянно прописывать конкретные адреса, а это энергозатратно для разработчиков и проблематично для пользователей.

То есть возникают проблемы с выборкой: она либо избыточна, либо недостаточна. REST не может предоставлять точные данные по запросу клиентов, потому что использует один endpoint для одного адреса.

Архитектурный стиль GraphQL позволяет сделать запросы за один раз. Клиент передаёт названия трёх мест, запрашивает нужные данные и ждёт. GraphQL выполнит все запросы и принесёт данные из разных адресов.

GraphQL: стандарт и его особенности

GraphQL — язык запросов для управления данными графов. Он использует разные виды протоколов для передачи информации. GraphQL в основном возвращает ответы в JSON.

Главное отличие GraphQL от REST API в том, что все данные клиент может выбрать всего одним запросом, даже если они будут располагаться в разных источниках. А в REST API придётся сделать выборку и извлекать их уже оттуда.

Разработчики считают GraphQL умным агрегатором, который играет роль оркестратора. Он переадресовывает фрагменты запроса на разные эндпоинты. GraphQL умеет отправлять данные поверх HTTP-протокола, Websocket и SSH. Это удобно, когда вы разрабатываете многофункциональное приложение.

GraphQL имеет три главных блока:

— Queries — запросы

— Schema — схема. Описание типов объектов и полей, принадлежащих каждому объекту

— Resolvers — функция, отвечающая за заполнение информацией полей в схеме. Способ выполнения процедуры определяет разработчик. Например, резолвер может извлекать данные из сервера или стороннего API

Для работы с графовым языком запросов есть утилита GraphiQL. Разработчик интегрирует её с Endpoint GraphQL. Он отправляет запрос серверу на предоставление своей схемы — вы получаете интерфейс для проведения тестов и изучения запросов.

Если с формированием запросов всё понятно, давайте посмотрим основные блоки кода для схем:

— Character — вид среды GraphQL

— Fields (например, name и address) — поля, заполняемые в виде объекта Character. Их находят в ответе на запрос. Каждое поле возвращает то значение, которое обрабатывает

Разберём поля подробно, потому что они составляют значительную часть возвращаемой информации. Итак, они могут быть скалярного вида, объектом, типом ввода, перечисления, объединения и интерфейсом.

Например, скалярные виды — это:

— String — определённые символы в коде UTF-8

— Int — 32-битное целое число

— Float — цифра с плавающим разделительным знаком

— Boolean — логическая информация: true или false

— ID — уникальный идентификатор. Нужен для повторной выборки объекта

GraphQL умеет анализировать синтаксис и проверять формы собственной схемой. Этот API может показаться сложным на стадии создания приложения, но подобное разделение на отдельные элементы — интересная возможность для анализа синтаксиса — позволяет получать чёткие ответы на запросы без дополнительных выборок, в отличие от REST API.
Основным минусом REST API считают создание множества эндпоинтов. Работать с ним — это как уточнять что-либо в разных компаниях. Нужно звонить всем по очереди.

Например, вы хотите посмотреть варианты пиццы и указываете точку /pizza. API принесёт информацию о цене, акциях и составе продукта. Но вы просили информацию о видах пиццы. Придётся постоянно прописывать конкретные адреса, а это энергозатратно для разработчиков и проблематично для пользователей.

То есть возникают проблемы с выборкой: она либо избыточна, либо недостаточна. REST не может предоставлять точные данные по запросу клиентов, потому что использует один endpoint для одного адреса.

Архитектурный стиль GraphQL позволяет сделать запросы за один раз. Клиент передаёт названия трёх мест, запрашивает нужные данные и ждёт. GraphQL выполнит все запросы и принесёт данные из разных адресов.

GraphQL: стандарт и его особенности

GraphQL — язык запросов для управления данными графов. Он использует разные виды протоколов для передачи информации. GraphQL в основном возвращает ответы в JSON.

Главное отличие GraphQL от REST API в том, что все данные клиент может выбрать всего одним запросом, даже если они будут располагаться в разных источниках. А в REST API придётся сделать выборку и извлекать их уже оттуда.

Разработчики считают GraphQL умным агрегатором, который играет роль оркестратора. Он переадресовывает фрагменты запроса на разные эндпоинты. GraphQL умеет отправлять данные поверх HTTP-протокола, Websocket и SSH. Это удобно, когда вы разрабатываете многофункциональное приложение.

GraphQL имеет три главных блока:

— Queries — запросы

— Schema — схема. Описание типов объектов и полей, принадлежащих каждому объекту

— Resolvers — функция, отвечающая за заполнение информацией полей в схеме. Способ выполнения процедуры определяет разработчик. Например, резолвер может извлекать данные из сервера или стороннего API

Для работы с графовым языком запросов есть утилита GraphiQL. Разработчик интегрирует её с Endpoint GraphQL. Он отправляет запрос серверу на предоставление своей схемы — вы получаете интерфейс для проведения тестов и изучения запросов.

Если с формированием запросов всё понятно, давайте посмотрим основные блоки кода для схем:

— Character — вид среды GraphQL

— Fields (например, name и address) — поля, заполняемые в виде объекта Character. Их находят в ответе на запрос. Каждое поле возвращает то значение, которое обрабатывает

Разберём поля подробно, потому что они составляют значительную часть возвращаемой информации. Итак, они могут быть скалярного вида, объектом, типом ввода, перечисления, объединения и интерфейсом.

Например, скалярные виды — это:

— String — определённые символы в коде UTF-8

— Int — 32-битное целое число

— Float — цифра с плавающим разделительным знаком

— Boolean — логическая информация: true или false

— ID — уникальный идентификатор. Нужен для повторной выборки объекта

GraphQL умеет анализировать синтаксис и проверять формы собственной схемой. Этот API может показаться сложным на стадии создания приложения, но подобное разделение на отдельные элементы — интересная возможность для анализа синтаксиса — позволяет получать чёткие ответы на запросы без дополнительных выборок, в отличие от REST API.
Основным минусом REST API считают создание множества эндпоинтов. Работать с ним — это как уточнять что-либо в разных компаниях. Нужно звонить всем по очереди.

Например, вы хотите посмотреть варианты пиццы и указываете точку /pizza. API принесёт информацию о цене, акциях и составе продукта. Но вы просили информацию о видах пиццы. Придётся постоянно прописывать конкретные адреса, а это энергозатратно для разработчиков и проблематично для пользователей.

То есть возникают проблемы с выборкой: она либо избыточна, либо недостаточна. REST не может предоставлять точные данные по запросу клиентов, потому что использует один endpoint для одного адреса.

Архитектурный стиль GraphQL позволяет сделать запросы за один раз. Клиент передаёт названия трёх мест, запрашивает нужные данные и ждёт. GraphQL выполнит все запросы и принесёт данные из разных адресов.

GraphQL: стандарт и его особенности

GraphQL — язык запросов для управления данными графов. Он использует разные виды протоколов для передачи информации. GraphQL в основном возвращает ответы в JSON.

Главное отличие GraphQL от REST API в том, что все данные клиент может выбрать всего одним запросом, даже если они будут располагаться в разных источниках. А в REST API придётся сделать выборку и извлекать их уже оттуда.

Разработчики считают GraphQL умным агрегатором, который играет роль оркестратора. Он переадресовывает фрагменты запроса на разные эндпоинты. GraphQL умеет отправлять данные поверх HTTP-протокола, Websocket и SSH. Это удобно, когда вы разрабатываете многофункциональное приложение.

GraphQL имеет три главных блока:

— Queries — запросы

— Schema — схема. Описание типов объектов и полей, принадлежащих каждому объекту

— Resolvers — функция, отвечающая за заполнение информацией полей в схеме. Способ выполнения процедуры определяет разработчик. Например, резолвер может извлекать данные из сервера или стороннего API

Для работы с графовым языком запросов есть утилита GraphiQL. Разработчик интегрирует её с Endpoint GraphQL. Он отправляет запрос серверу на предоставление своей схемы — вы получаете интерфейс для проведения тестов и изучения запросов.

Если с формированием запросов всё понятно, давайте посмотрим основные блоки кода для схем:

— Character — вид среды GraphQL

— Fields (например, name и address) — поля, заполняемые в виде объекта Character. Их находят в ответе на запрос. Каждое поле возвращает то значение, которое обрабатывает

Разберём поля подробно, потому что они составляют значительную часть возвращаемой информации. Итак, они могут быть скалярного вида, объектом, типом ввода, перечисления, объединения и интерфейсом.

Например, скалярные виды — это:

— String — определённые символы в коде UTF-8

— Int — 32-битное целое число

— Float — цифра с плавающим разделительным знаком

— Boolean — логическая информация: true или false

— ID — уникальный идентификатор. Нужен для повторной выборки объекта

GraphQL умеет анализировать синтаксис и проверять формы собственной схемой. Этот API может показаться сложным на стадии создания приложения, но подобное разделение на отдельные элементы — интересная возможность для анализа синтаксиса — позволяет получать чёткие ответы на запросы без дополнительных выборок, в отличие от REST API.
13:39
+3
Хороший обзор, спасибо. Хотелось бы в будущем почитать более продвинутую версию.
Хороший обзор, спасибо. Хотелось бы в будущем почитать более продвинутую версию.
Хороший обзор, спасибо. Хотелось бы в будущем почитать более продвинутую версию.
13:38
+1
Хороший обзор, спасибо. Хотелось бы в будущем почитать более продвинутую версию.
который каждую маломальскую сущнусь стремился усложнить по максимому.

Сложно угадать что вы имели введу, но возможно то, что математик пытался бежать впереди поровоза в духе «я знаю что это потом понадобиться». Не, это неправильно, это зло.

Но, если у нас предметная область различается хоть на 1 поле, тогда:

Сущность user уже с первых строк кода могла быть реализовнана как целая домення область из user-core, user-address, credentials, user audit, connected apps, payment data

Это правильно. Хороший контекст и домен превыше всего. Вообще всего. Потому что это залог:
1. минимизации ошибок в реализации
2. минимизации скрытых ошибок и сайд-эффектов
3. возможности передать код след. разработчику, и позволить ему разобраться в нём так, что тот выполнит п.1. и 2.
Можно жить с низкой производительностью — её можно улучшить. Можно жить с техническими багами реализации или недоделками (ну типа нет 100500 валидации на такое-то условие) — их можно исправить. Нельзя существовать с продуктом, которые делает не то, что нужно, да ещё и скрыто. И при этом не позволяет себя исправить ( например исправление только за счёт костылей, что вносит сумятицу и сайд-эффекты. разраб уволился, с ним и знание «а почему так», а код и контекст не говорят почему)

Но конечно, заготовки делать на случай просматривающегося контекста — это тоже зло. Разработка и развитие предметной области сродне лепки из пластилина или глины (обратное резьбе по камню): меся обрастает, потом переосмысление, рефакторинг всего. Если есть опыт, то рефакторинг проходит легко. Если говнокодили в начале, то с болью. Но нужно развивать доменную область, которая отображает фактическую модель систему — а не:
а) изначально запланированную, но которая оказалось избыточной\недоделанной
б) изначально незапланированную, но вылепленную без «развития», а потому таскающую за собой кучу легаси свойств и зависимостей из других контекстов, которые поленились создать\не поняли что надо создать.

почемуто раз в 5 больше ненужных усложнений в виде сущностей.
Слава Богу его можно было убедить словами и рефакторинг он не воспринимал болезненно.

Ну это и есть то самое развитие. Насоздавал. Понял что 5 из 8 сущностей лишние или дубли — удалил. Это норма.
Если рефакторинг перед началом каждой новой задачи, во время изменения куска кода или фикса бага то и нет проблем с поступательным развитием. А если рефакторинг — это плановая задача «вернуть тех. долг», то всё, считай нет и не будет его никогда.
Браво! особенно по первой части.

не совсем так думаю про:

Не создавайте ненужных сущностей без необходимости.

мне всегда казалось это о другом
Например я работал как-то в одной команде с отличным матиматиком (притворяющимся программистом ;) очень не плохо в целом) который каждую маломальскую сущнусь стремился усложнить по максимому.
Сущность user уже с первых строк кода могла быть реализовнана как целая домення область из user-core, user-address, credentials, user audit, connected apps, payment data
и так со всеми остальными, тоесть в среденм в его коде по сравнению со всеми остальными было почемуто раз в 5 больше ненужных усложнений в виде сущностей.
Слава Богу его можно было убедить словами и рефакторинг он не воспринимал болезненно. Но я всегда впоминал именно этот принцип и его ужасное нарушение. Может я конечно что-то не так понял. ;)
Дублирование кода – пустая трата времени и ресурсов. Вам придется поддерживать одну и ту же логику и тестировать код сразу в двух местах, причем если вы измените код в одном месте, его нужно будет изменить и в другом.

Вот это лютый бред и трешак, который привёл к монолитизации и колоссальному увеличению связанности и мешает людям подняться на ступень выше в написании качественного кода. С ним возятся до сих пор, хотя больше плохого, чем хорошего. Ну при условии что вы не мамкин сайт домашний пишите, а приложение миллионов на 5-7 строк кода. Он актуален исключительно в среде теоретиков и джунов, чтобы последние не копипастили один и тот же код в разных классах.
На практике, люди, упоротые этим принципом и не знающие других подходов с огромной болью живут в огромном монолитие с единой dll типа DAL единой dll типа DomainModel и т.д.
Всё это таскается из одного проекта в другой, шарится между десятками сервисов и апи и потом распилить такое на микро сервисы просто невозможно, точнее бизнес не хочет. Цена поддержки растёт кратно. Зато без копирования, ага.

Как нужно делать:
1. Не копировать код в рамках 1 класса и одной, при возможности одной dll.
2. Делать всё в рамках одной фичи. А ля микросервис. Это означает что нет никаких папок с кучей разных репозиотриев а ля Reposotories/AccountRepository и тут же Reposotories/OrdersRepository. А есть 2 фичи (Accounts/ Orders/) внутри которых есть такие репо (Accounts/AccountRepo, Accounts/AccountFactory, Orders/OrderRepo...). В будущем это позволит разделить контексты И если вдруг фиче про ордера нужен доступ к данным из аккаунта, то да, копипастится логика хоть полностью и делается свой репо (Orders/AcountForOrdersRepo… ). Менять её придётся разве что раз в 1000 лет. А вот поддерживать и менять в рамках одной фичи — сколько угодно раз. И нафига тогда нужен такая связанность с Account фичей? Нет уж.
3. По мере разрастания кода — разносить вообще в разные библиотеки (контексты) и репозитории.
А DRY на помойку.

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

Это тоже теоретическая чушь, которая на практике сводится к:
1) мы уже делали такое и знаем что примерно нужно сделать ещё раз. Тогда проблемы нет.
2) мы ещё не делали такое и хз что нас ждёт. В этом случае ничего не поможет, ничего не угадать. Например мы на своём проекте несколько лет использовали singlar для для работы множества клиентов с сервером и сервер с очередью через RebbitMQ. В итоге отказались от подхода, как нестабильного, перешли на realtime запрос-ответ. Угадать заранее, фактически без прототипа в продакшене такое было невозможно.
Что же на самом деле лучше сделать в таком случае?
а) Изучить максимум инфы по данной технологии.
б) делать простые небольшие изолированные куски. Потом с увеличением их числа вовремя рефакторить и объединять в контексты. Постоянный рефакторинг — только он поможет избежать факапа. А рефакторинг подразумевает поднятие на уровень выше в архитектуре и её пересмотр в том числе. Когда время пришло.

SOLID

Вот это must have и за его нарушение (чаще всего S) увольнять к чертям. Оно хоть как-то спасает от связанности и роста проблем.

Не создавайте ненужных сущностей без необходимости.

Очередной теоретический бред для джунов, наверное. Сущности всегда создаются в зависимости от контекста и бизнеса. Если у тебя 5 вариантов работы с ордерами и в одном случае нужны одни поля, а в другом — другие и только id + name общие, то это разные сущности. И их нужно создавать. А не гонять одну God object по всему домену. Увеличивая связанность. Если тебе нужно вернуть объект в виде json то не нужно возвращать сущность из предметной области. Пусть она хоть 1 в 1 пока совпадает с DTO объектом. Ключевое слово тут «пока» совпадает.

Фаулер и Макконели верно говорят, что самое дорогое — поддержка. А поддержка дорожает с увеличением сложности. А сложность в том числе берётся и от связанность, из-за невозможности просто удалить и заново переписать кусок. А вдруг кому-то что-то сломает?!

Солид противоречит ягни, драй и кису. То есть конечно, иногда они успешно сосуществуют в некоторых местах. Но есть достаточно слуачев когда надо выбирать. И я агитирую за выбор солида.
Хорошему программисту необходимо уметь совмещать свои навыки со здравым смыслом. Все дело в прагматизме и навыке выбора лучшего решения для вашей проблемы. Когда вы сталкиваетесь с проблемой при разработке ПО, вы можете воспользоваться базовыми принципами, которые помогут в выборе самого правильного подхода.

В этом тексте приводится набор принципов, которые должен знать любой разработчик, и которые следует периодически освежать в памяти. Считайте их своим секретным оружием при программировании.

Последовательное применение этих принципов упростит ваш переход от миддла к сеньору. Вы можете обнаружить, что некоторые (вероятно) вы применяете интуитивно.

Принципов много. Мы остановимся на семи самых важных. Их использование поможет вам в развитии и позволит стать лучшим программистом.

1. YAGNI

You Aren’t Gonna Need It / Вам это не понадобится

Этот принцип прост и очевиден, но ему далеко не все следуют. Если пишете код, то будьте уверены, что он вам понадобится. Не пишите код, если думаете, что он пригодится позже.

Этот принцип применим при рефакторинге. Если вы занимаетесь рефакторингом метода, класса или файла, не бойтесь удалять лишние методы. Даже если раньше они были полезны – теперь они не нужны.

Может наступить день, когда они снова понадобятся – тогда вы сможете воспользоваться git-репозиторием, чтобы воскресить их из мертвых.

2. DRY

Don’t Repeat Yourself / Не повторяйтесь

Эта концепция была впервые сформулирована в книге Энди Ханта и Дэйва Томаса «Программист-прагматик: путь от подмастерья к мастеру».

Идея вращается вокруг единого источника правды (single source of truth — SSOT). Что это вообще такое?

В проектировании и теории информационных систем единый источник истины (SSOT) – это практика структурирования информационных моделей и схемы данных, которая подразумевает, что все фрагменты данных обрабатываются (или редактируются) только в одном месте… SSOT предоставляют достоверные, актуальные и пригодные к использованию данные.
Использование SSOT позволит создать более прочную и понятную кодовую базу.

Дублирование кода – пустая трата времени и ресурсов. Вам придется поддерживать одну и ту же логику и тестировать код сразу в двух местах, причем если вы измените код в одном месте, его нужно будет изменить и в другом.

В большинстве случаев дублирование кода происходит из-за незнания системы. Прежде чем что-либо писать, проявите прагматизм: осмотритесь. Возможно, эта функция где-то реализована. Возможно, эта бизнес-логика существует в другом месте. Повторное использование кода – всегда разумное решение.

3. KISS

Keep It Simple, Stupid / Будь проще

Этот принцип был разработан ВМС США в 1960 году. Этот принцип гласит, что простые системы будут работать лучше и надежнее.

У этого принципа много общего с переизобретением колеса, которым занимались в 1970-х. Тогда он звучал как деловая и рекламная метафора.

Применительно к разработке ПО он значит следующее – не придумывайте к задаче более сложного решения, чем ей требуется.

Иногда самое разумное решение оказывается и самым простым. Написание производительного, эффективного и простого кода – это прекрасно.

Одна из самых распространенных ошибок нашего времени – использование новых инструментов исключительно из-за того, что они блестят. Разработчиков следует мотивировать использовать новейшие технологии не потому, что они новые, а потому что они подходят для работы.

4. Big Design Up Front

Глобальное проектирование прежде всего

Этот подход к разработке программного обеспечения очень важен, и его часто игнорируют. Прежде чем переходить к реализации, убедитесь, что все хорошо продумано.

Зачастую продумывание решений избавляло нас от проблем при разработке… Внесение изменений в спецификации занимало час или два. Если бы мы вносили эти изменения в код, на это уходили бы недели. Я даже не могу выразить, насколько сильно я верю в важность проектирования перед реализацией, хотя адепты экстремального программирования предали эту практику анафеме. Я экономил время и делал свои продукты лучше, используя BDUF, и я горжусь этим фактом, чтобы там ни говорили фанатики экстремального программирования. Они просто ошибаются, иначе сказать не могу.

Многие разработчики считают, что если они не пишут код, то они не добиваются прогресса. Это неверный подход. Составив план, вы избавите себя от необходимости раз за разом начинать с нуля.

Иногда в недостатках и процессах разработки архитектуры должны быть замешаны и другие люди. Чем раньше вы все это обсудите, тем лучше будет для всех.

Очень распространенный контраргумент заключается в том, что стоимость решения проблем зачастую ниже стоимости времени планирования. Чем с меньшим количеством ошибок столкнется пользователь, тем лучше будет его опыт. У вас может не быть другого шанса справиться с этими ошибками.

5. SOLID

Это наиболее известный принцип разработки ПО. Solid — это аббревиатура от:

S) Single-responsibility principle /Принцип единственной ответственности

Его важность невозможно переоценить. Каждый объект, класс и метод должны отвечать только за что-то одно. Если ваш объект/класс/метод делает слишком много, вы получите спагетти-код. Вот пример:

const saveTodo = async () => {
    try {
        response = await saveTodoApi(); 
        showSuccessPop('Success'); 
        window.location.href = '/successPage';
    } catch (error) { 
        showErrorPopup(`Error: ${error} `);
    }
}


Этот метод кажется безобидным, но на самом деле он делает слишком много:

— Сохраняет объект
— Обрабатывает уведомление в UI
— Выполняет навигацию

Еще один побочный эффект такого кода – проблемы с тестированием. Запутанный функционал тестировать сложно.

O) Open–closed principle / Принцип открытости-закрытости

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

Хороший способ решения этой проблемы – использование наследования. В JavaScript эта проблема решается с помощью композиции.

Простое правило: если вы изменяете сущность, чтобы сделать ее расширяемой, вы впервые нарушили этот принцип.

L) Liskov substitution principle / Принцип подстановки Лисков

Этот принцип гласит, что объекты старших классов должны быть заменимы объектами подклассов, и приложение при такой замене должно работать так, как ожидается.

I) Interface segregation principle / Принцип разделения интерфейсов

Этот принцип был сформулирован Робертом Мартином, когда он консультировал Xerox, и он очевиден.

Объекты не должны зависеть от интерфейсов, которые они не используют

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

Убедитесь, что вы не заставляете объекты реализовывать методы, которые им никогда не понадобятся. Вот пример:

interface Animal {
  eat: () => void;
  walk: () => void;
  fly: () => void;
  swim: () => void;
}


Не все животные могут fly, walk или swim, поэтому эти методы не должны быть частью интерфейса или должны быть необязательными.

D) Dependency inversion principle / Принцип инверсии зависимостей

Этот принцип невозможно переоценить. Мы должны полагаться на абстракции, а не на конкретные реализации. Компоненты ПО должны иметь низкую связность и высокую согласованность.

Заботиться нужно не о том, как что-то устроено, а о том, как оно работает. Простой пример – использование дат в JavaScript. Вы можете написать для них свой слой абстракции. Тогда если у вас сменится источник получения дат, вам нужно будет внести изменения в одном месте, а не в тысяче.

Иногда добавление этого уровня абстракции требует усилий, но в конечном итоге они окупаются.

В качестве примера взгляните на date-io, в этой библиотеке создан тот уровень абстракции, который позволяет вам использовать её с разными источниками дат.

6. Avoid Premature Optimization

Избегайте преждевременной оптимизации

Эта практика побуждает разработчиков оптимизировать код до того, как необходимость этой оптимизации будет доказана. Думаю, что если вы следуете KISS или YAGNI, вы не попадетесь на этот крючок.

Поймите правильно, предвидеть, что произойдет что-то плохое – это хорошо. Но прежде чем вы погрузитесь в детали реализации, убедитесь, что эти оптимизации действительно полезны.

Очень простой пример – масштабирование. Вы не станете покупать 40 серверов из предположения, что ваше новое приложение станет очень популярным. Вы будете добавлять серверы по мере необходимости.

Преждевременная оптимизация может привести к задержкам в коде и, следовательно, увеличит затраты времени на вывод функций на рынок.

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

7. Бритва Оккама

Бри́тва О́ккама (иногда ле́звие О́ккама) — методологический принцип, в кратком виде гласящий: «Не следует множить сущее без необходимости» (либо «Не следует привлекать новые сущности без крайней на то необходимости»).

Что это значит в мире программирования? Не создавайте ненужных сущностей без необходимости. Будьте прагматичны — подумайте, нужны ли они, поскольку они могут в конечном итоге усложнить вашу кодовую базу.

Эти принципы не очень сложны. На самом деле, именно простота делает их красивыми. Если вы сбиты с толку, не пытайтесь применять все их сразу. Просто постарайтесь работать осознанно и пробуйте постепенно включать эти принципы в свой рабочий процесс.

Использование базовых, но действенных принципов позволит вам стать лучшим программистом и иметь более четкое представление о том, почему вы что-то делаете.

Если вы применяете большую часть принципов интуитивно, стоит задумываться и осознавать почему вы делаете что-то определенным образом.
Спасибо за столько широкий ответ, а что тогда насчет принципов для разработки: KISS, DRY, YAGNI, BDUF, SOLID, APO и бритва Оккама?

Заявка на услуги DST

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

Адрес

Ижевск, ул. Воткинское шоссе 170 Е.
Региональный оператор Сколково. Технопарк Нобель

8 495 1985800
Заказать звонок

Режим работы: Пн-Пт 10:00-19:00

info@dstglobal.ru

Задать вопрос по почте

Укажите ваше имя
Укажите ваше email
Укажите ваше телефон