RSS

Комментарии

Плюсы 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
Хороший обзор, спасибо. Хотелось бы в будущем почитать более продвинутую версию.
Хороший обзор, спасибо. Хотелось бы в будущем почитать более продвинутую версию.
Хороший обзор, спасибо. Хотелось бы в будущем почитать более продвинутую версию.
Хороший обзор, спасибо. Хотелось бы в будущем почитать более продвинутую версию.
который каждую маломальскую сущнусь стремился усложнить по максимому.

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

Но, если у нас предметная область различается хоть на 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 и бритва Оккама?
TDD — Test Driven Development

TDD — это методология разработки ПО, которая основывается на повторении коротких циклов разработки: изначально пишется тест, покрывающий желаемое изменение, затем пишется программный код, который реализует желаемое поведение системы и позволит пройти написанный тест. Затем проводится рефакторинг написанного кода с постоянной проверкой прохождения тестов.

Звучит просто и понятно. Многим знаком такой подход к разработке и даже сам «Uncle Bob» активно его пропагандирует:

«TDD считается одной из форм правильного метода построения приложения. Философия разработки на основе тестов заключается в том, что ваши тесты являются спецификацией того, как ваша программа должна вести себя. Если вы рассматриваете свой набор тестов как обязательную часть процесса сборки, если ваши тесты не проходят, программа не собирается, потому что она неверна. Конечно, ограничение заключается в том, что правильность вашей программы определена только как полнота ваших тестов. Тем не менее, исследования показали, что разработка, основанная на тестировании, может привести к снижению ошибок на 40-80% в производстве.»

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

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

Эта методология позволяет добиться создания пригодного для автоматического тестирования приложения и очень хорошего покрытия кода тестами, так как ТЗ переводится на язык автоматических тестов, то есть всё, что программа должна делать, проверяется. Также TDD часто упрощает программную реализацию: исключается избыточность реализации — если компонент проходит тест, то он считается готовым.

Архитектура программных продуктов, разрабатываемых таким образом, обычно лучше (в приложениях, которые пригодны для автоматического тестирования, обычно очень хорошо распределяется ответственность между компонентами, а выполняемые сложные процедуры декомпозированы на множество простых). Стабильность работы приложения, разработанного через тестирование, выше за счёт того, что все основные функциональные возможности программы покрыты тестами и их работоспособность постоянно проверяется. Сопровождаемость проектов, где тестируется всё или практически всё, очень высока — разработчики могут не бояться вносить изменения в код, если что-то пойдёт не так, то об этом сообщат результаты автоматического тестирования.

Подробнее с принципами TDD вы можете ознакомиться, прочитав книгу Кента Бека «Экстремальное программирование. Разработка через тестирование».

TDD — Type Driven Development

Type Driven Development сокращенно пишется также, как и разработка через тестирование, поэтому обычно пишут полное название.

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

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

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

Из минусов только возрастающая сложность у языков с динамической типизацией. К примеру, для JavaScript этот подход тяжелее применить, чем для TypeScript.

BDD — Behaviour Driven Development

Из-за некоторого методологического сходства TDD (Test Driven Development) и BDD (Behaviour Driven Development) часто путают даже профессионалы. В чем же отличие? Концепции обоих подходов похожи, сначала идут тесты и только потом начинается разработка, но предназначение у них совершенно разное. TDD — это больше о программировании и тестировании на уровне технической реализации продукта, когда тесты создают сами разработчики.

BDD предполагает описание тестировщиком или аналитиком пользовательских сценариев на естественном языке — если можно так выразиться, на языке бизнеса. BDD — behaviour-driven development — это разработка, основанная на описании поведения. Определенный человек(или люди) пишет описания вида «я как пользователь хочу когда нажали кнопку пуск тогда показывалось меню как на картинке» (там есть специально выделенные ключевые слова). Программисты давно написали специальные инструменты, которые подобные описания переводят в тесты (иногда совсем прозрачно для программиста). А дальше классическая разработка с тестами.

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

Тексты сценариев записываются в определенной форме.

BDD подход совместно с инженерными практиками позволил нам отказаться от legacy-документации, содержащей неактуальную информацию, и получать новую документацию на лету, хранить ее вместе с проектом, что приблизило аналитиков и тестировщиков к коду.

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

В чем преимущество BDD?

— Тесты читаемые для не программистов.
— Их легко изменять. Они часто пишутся почти на чистом английском.
— Их может писать product owner или другие заинтересованные лица.
— Результаты выполнения тестов более «человечные».
— Тесты не зависят от целевого языка программирования. Миграция на другой язык сильно упрощается.

Минусы:

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

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

Подробнее о BDD можно прочитать тут.

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

DDD — Domain Driven Design

Предметно-ориентированное проектирование не является какой-либо конкретной технологией или методологией. DDD — это набор правил, которые позволяют принимать правильные проектные решения. Данный подход позволяет значительно ускорить процесс проектирования программного обеспечения в незнакомой предметной области.

Предметно-ориентированное проектирование (реже проблемно-ориентированное, англ. Domain-driven design, DDD) — это набор принципов и схем, направленных на создание оптимальных систем объектов. Процесс разработки сводится к созданию программных абстракций, которые называются моделями предметных областей. В эти модели входит бизнес-логика, устанавливающая связь между реальными условиями области применения продукта и кодом.

Подход DDD особо полезен в ситуациях, когда разработчик не является специалистом в области разрабатываемого продукта. К примеру: программист не может знать все области, в которых требуется создать ПО, но с помощью правильного представления структуры, посредством предметно-ориентированного подхода, может без труда спроектировать приложение, основываясь на ключевых моментах и знаниях рабочей области.

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

Основная цель Domain-Driven Design — это борьба со сложностью бизнес-процессов, их автоматизации и реализации в коде. «Domain» переводится как «предметная область», и именно от предметной области отталкивается разработка и проектирование в рамках данного подхода.

Ключевым понятием в DDD является «единый язык» (ubiquitous language). Ubiquitous language способствует прозрачному общению между участниками проекта. Единый он не в том смысле, что он один на все случаи жизни. Как раз наоборот. Все участники общаются на нём, всё обсуждение происходит в терминах единого языка, и все артефакты максимально должны излагаться в терминах единого языка, то есть, начиная от ТЗ, и, заканчивая кодом.

Следующим понятием является «доменная модель». Данная модель представляет из себя словарь терминов из ubiquitous language. И доменная модель, и ubiquitous language ограничены контекстом, который в Domain-Driven Design называется bounded context. Он ограничивает доменную модель таким образом, чтобы все понятия внутри него были однозначными, и все понимали, о чём идёт речь.

Пример: возьмем сущность «человек» и поместим его в контекст «публичные выступления». В этом контексте, по DDD, он становится спикером или оратором. А в контексте «семья» — мужем или братом.

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

Если в языке проекта вы используете выражения «продукт был добавлен», то следующий вариант не по DDD:

var product = new Product('apple')product.save()


Почему? В коде написано, что мы создали продукт странным образом и сохранили его. Как же все таки добавить продукт? Нужно его добавить. Вот DDD код:

Product::add('apple');


Архитектура:

С точки зрения Domain-Driven Design абсолютно всё равно, какую архитектуру вы выберете. Domain-Driven Design не про это, Domain-Driven Design про язык и про общение.

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

Про DDD также есть статьи, которые я очень советую прочитать внимательно — тут и тут.

Что же нам это дает в итоге:
— почти все участники команды могут читать код проекта;
— постановка задач становится более явной;
— баги бизнес логики становиться проще искать;
— QA специалистам намного легче просматривать код и находить логические ошибки и баги.

Минусы:
— требуется высокая квалификация разработчиков, особенно, на старте проекта;
— не все клиенты готовы пойти на такие затраты, DDD нужно учиться всем участникам процесса разработки.

FDD — Features Driven Development

FDD — Эта методология (кратко именуемая FDD) была разработана Джеффом Де Люка (Jeff De Luca) и признанным гуру в области объектно-ориентированных технологий Питером Коадом (Peter Coad). FDD представляет собой попытку объединить наиболее признанные в индустрии разработки программного обеспечения методики, принимающие за основу важную для заказчика функциональность (свойства) разрабатываемого программного обеспечения. Основной целью данной методологии является разработка реального, работающего программного обеспечения систематически, в поставленные сроки.

Как и остальные адаптивные методологии, она делает основной упор на коротких итерациях, каждая из которых служит для проработки определенной части функциональности системы. Согласно FDD, одна итерация длится две недели. FDD насчитывает пять процессов. Первые три из них относятся к началу проекта:

— разработка общей модели;
— составление списка требуемых свойств системы;
— планирование работы над каждым свойством;
— проектирование каждого свойства;
— конструирование каждого свойства.

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

Давайте поподробнее остановимся на каждом пункте.

Разработка общей модели

Разработка начинается c анализа широты имеющегося круга задач и контекста системы. Далее для каждой моделируемой области делается более детальный разбор. Предварительные описания составляются небольшими группами и выносятся на дальнейшее обсуждение и экспертную оценку. После одна из предлагаемых моделей или их совокупность становится моделью для конкретной области. Модели каждой области задач объединяются в общую итоговую модель, которая может изменяться в течение работы.

Составление списка функций

Информация, собранная при построении общей модели, используется для составления списка функций. Функции объединяются в так называемые «области» (англ. domain), а они же в свою очередь делятся на подобласти (англ. subject areas) по функциональному признаку.

Каждая подобласть соответствует определенному бизнес-процессу, а его шаги становятся списком функций (свойств). Функции представлены в виде «действие — результат — объект», например, «проверка пароля пользователя». Разработка каждой функции должна занимать не более 2 недель, иначе задачу необходимо декомпозировать на более мелкими итерации. Список свойств в FDD – то же самое, что и product backlog в SCRUM.

План по свойствам (функциям)

Далее идет этап распределения функций среди ведущих программистов или по командам.

Проектирование функций

Для каждого свойства создается проектировочный пакет. Ведущий программист выделяет небольшую группу свойств для разработки в течение двух недель. После оставляются подробные диаграммы последовательности для каждого свойства, уточняя общую модель. Далее пишутся «заглушки» классов и методов. В этот момент мы должны сфокусироваться на дизайне программного продукта.

Реализация функции

На пути к эффективному тестированию: выбираем лучшую TMS

Пишем код, убираем заглушки, тестируем.

После того, как свойство протестировано и ушло в продукт, берем следующее по приоритетам свойство, повторяем цикл дизайна/реализации.

Итого, в результате мы получаем:
— документация по свойствам системы;
— тщательное проектирование;
— проще оценивать небольшие задачи;
— тесты ориентированы на бизнес-задачи;
— проработанный процесс создания продукта;
— короткие итеративные циклы разработки позволяют быстрее наращивать функциональность и уменьшить количество ошибок.

Минусы:
— FDD больше подходит для больших проектов. Небольшие команды разработки не смогут прочувствовать все преимущества данного подхода;
— значительные затраты на внедрение и обучение.

MDD — Model Driven Development

В последнее время много внимания в публикациях отводится теме архитектуры и разработке на основе моделей MDA (Model Driven Architecture) и MDD (Model Driven Development). Не вдаваясь в подробности, выделим только ключевые моменты.

Разработка, управляемая моделями, (англ. model-driven development) — это стиль разработки программного обеспечения, когда модели становятся основными артефактами разработки, из которых генерируется код и другие артефакты.

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

Основная цель MDD — минимизация затрат, связанных с привязкой к конкретным системным платформам и программным инфраструктурам. Ведь основная бизнес-логика содержится в диаграммах и не сковывает нас рамками выбора языка программирования и инструментов разработки.

Давайте немного отвлечемся и вспомним про компилятор. Он преобразует язык программирования высокого уровня в эквивалентную реализацию на машинном языке. Моделью в этом случае является программа, написанная на языке высокого уровня, которая скрывает несущественные детали о ее реализации. В MDD наши диаграммы — это еще один уровень абстракции, который не позволяет нам увязнуть в деталях разработки, а посмотреть на картину в целом.

Диаграммы выступают в качестве своеобразных «чертежей», из которых различные автоматизированные и полуавтоматизированные процессы извлекают программы и соответствующие модели. Причем автоматическая генерация кода варьируется от извлечения простого скелета приложения до получения конечной кодовой базы (что сравнимо с традиционной компиляцией).

Идея MDD не нова ‑ она использовались с переменным успехом и раньше. Причиной возросшего внимания к ним в настоящее время является то, что автоматизации поддается значительно больше процессов, чем раньше. Это развитие отражается в появлении MDD-стандартов, что ведет к унификации соответствующих средств. Одним из таких стандартов является пересмотренная версия Unified Modeling Language – UML 2.0.

По стандартам Object Management Group (OMG) создание приложения состоит из следующих шагов:

— cначала разрабатывается модель предметной области проектируемого приложения, полностью независимая от имплементирующей технологии;
— затем она трансформируется специальным инструментом в платформо-зависимую модель;
— наконец, она переводится в исходный код на соответствующем языке программирования.
Классический пример применения MDD, который используется уже давно, — моделирование баз данных. На основе одной концептуальной модели данных вы можете поддерживать несколько связанных с ней физических моделей для различных СУБД.

Какие преимущества мы получаем:
— ускоряется вывод минимального жизнеспособного продукта (Minimum Viable Product) на рынок;
— сокращается время на: генерацию каркаса приложения, модели классов, базы данных;
— постоянно обновляемая документация;
— для участников проекта диаграммы намного нагляднее кода.

Минусы:
— для внедрение MMD потребуется использовать специальные программные решения, такие как Rational Software Architect, Simulink или Sirius;
— от программистов требуются внушительные знания проектирования диаграмм;
— значительные финансовые затраты на интеграцию данной методологии.

PDD — Panic Driven Development

Если вы пробовали методологии agile разработки, то вы наверняка пробовали и PDD. Давайте посмотрим более подробно, каковы принципы этой методологии.

Новые задачи приоритетнее старых

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

Пишите столько кода, сколько нужно, чтобы решить проблему

Разработчики пишут код для жизни. Ошибки могут быть исправлены только кодом. Обсуждение дизайна и UX может только замедлить разработку. Но мы же не хотим терять драгоценное время? Сначала напишите решение, потом проверьте своё предположение по исправлению. Если исправление работает, проблема решена.

Тесты должны писаться в конце

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

Доверьтесь своему инстинкту

Программирование — это искусство. Искусство имеет внутреннюю инстинктивную составляющую. Доверься своей интуиции. Напишите код. Разверните его. Только смелым улыбается удача.

Процесс гибок

Любой процесс, созданный для разработки, тестирования и выпуска программного обеспечения, — это просто набор соглашений и правил, которые не высечены в камне. Критические исправления требуют разных подходов. Ожидается, что вы согнёте процесс, чтобы выполнить задачу в срок, если этого требует бизнес.

Это процесс, управляемый менеджером

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

Плюсы подхода:
— высокая скорость разработки;
— дешево;
— заказчики счастливы, что наконец-то нашли толковых разработчиков.

Минусы:
— все плюсы разобьются о технический долг и сложность проекта.

PDD своеобразный антипаттерн разработки, который, к сожалению, мы все время от времени практикуем.
Просматривая статьи по проектированию ПО, я постоянно встречаю тучу невиданных сокращений и вскользь упоминаемых практик разработки — TDD, BDD, DDD, FDD, MDD и PDD

— TDD — ну, это все знают, сначала пишем тесты, а потом остальной код.
— BDD — что-то знакомое, вроде как, тоже тесты, но особенные.
— TDD — снова? Так, стоп, тут речь уже не о тестах совсем. Но почему называется так же?
— DDD — bound contexts, ubiquitous language, domain…
— FDD — да сколько можно?
— MDD — cерьезно, на основе диаграмм?
— PDD —…

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

Что нужно сделать:
— Выполнить внутреннюю и внещнюю оптимизацию сайта.

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

— Каждый день публиковать на сайте 1-3 статьи, каждая из которых должна быть написана на свою группу ключевых запросов из семантического ядра. Статьи можете писать сами или заказывать на бирже купли продажи статей. Уникальность должна быть 100%. Публикацию статей продолжать до 12 месяцев и более, желательно каждый день без перерывов. Позже регулярность сохраняем, но публикуем 2-4 раза в неделю.

— При публикации статей на сайте, делайте внутреннюю перелинковка статей сайта по кругу. Это, когда в одной статье стоит ссылка на другую и т.д. по кругу.

— Через 5-6 месяцев определите статьи для продвижения и с других статей сайта проставьте на них ссылки (анкорные). Для этого подойдут ключевые запросы, которые использовали при написании продвигаемой статьи.

— Наните получать статейные ссылки (в этом поможет биржа Миралинкс, сначала получаем с близкий по тематике сайтов, когда они закончатся, с новостных) и с форумов (можете заказать размещение постов в тематических ветках обсуждений, например на бирже Адвего). 80% ссылок должны быть вида url адреса продвигаемой статьи, 10% вида: тут, здесь, на этом сайте и т.д., остальные 20% анкорные. Статейные ссылки и отзывы получайте каждый месяц, не прекращая этот процесс. И не забывайте получать статейные и форумные ссылки и на другие старницы сайта. которые не продвигаете.

— Получение отзывов с указанием url ссылки на сайт или упоминание названия сайта в отзыве.

— Запускаем рекламу в Яндекс директ в Поиске и в РСЯ, выставляем недорогую цену клика, чтобы регулярно получать трафик Рекламу в Яндексе можете запустить на сайт через 2-3 месяца после начала публикаций на нем статей, установите недорогие цены за клик и пусть работает.

— И никакого черного и серого seo не используйте.

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

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

Адрес

Ижевск, ул. Воткинское шоссе, д. 170 Е, Технопарк Нобель, офис 1117

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

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

info@dstglobal.ru

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

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