Про важность документирования

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

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

2. HLA (high level architecture). Это документ описывает на уровне архитектуры, как мы будем реализовывать то, что описано в ТЗ. Расписывается, в какие места будет необходимо внести изменения, описывается суть изменений, и именно в этом документе описывается такая очень важная часть, как интерфейсы между модулями/подсистемами. Если не ошибаюсь, у ДеМарко и Листера было очень верно было отмечено, что самые «плохие» (то есть сложные в поиске и ликвидации) баги возникают при взаимодействии между системами, в интерфейсах. Так как HLA согласуется группами разработки, то, фактически, этот документ является тем единым местом, в котором группы разработки соглашаются, как их продукты будут взаимодействовать между собой. Если вы не будете писать эти документы, то вы никогда не найдете, кто неверно реализовал интерфейс, что в итоге непременно приведет к ошибкам в архитектуре, которые в будущем могут обойтись весьма большими издержками. Сильно упадет качество кода, возникнет масса труднолокализуемых ошибок. Кроме того, в будущем, для того, чтобы понять, как устроено взаимодействие между двумя модулями, новому человеку опять же придется общаться с десятками людей и поднимать месяцы переписки.

3. LLD (low level decomposition). Это документ, который создается внутри группы разработки. Он подробно описывает все необходимые к реализации методы и API. Фактически, после написания этого документа остается лишь закодировать описанное. Без этого документа программисты не будут иметь четкого понимания, что необходимо сделать, что в дальнейшем приведет к росту количества багов (то есть к снижению качества кода).

4. ПМИ (программа и методика испытаний). Это, пожалуй, основной документ из области тестирования, пошагово описывающий, что необходимо сделать для того, чтобы бизнес однозначно решил, что реализованный функционал работает корректно и согласно ТЗ. Без такого документа вы не сможете проверить функционал на предмет ошибок (несоответствие ТЗ — тоже баг), что в итоге сильно повысит риск того, что на производственной платформе вылезет куча багов, вплоть до полной неработоспособности функционала. Кроме того, без этого документа приёмка функционала бизнесом превращается в неформализованный процесс со всеми вытекающими из этого последствиями типа необоснованных претензий к разработке со стороны бизнеса.

5. Руководство пользователя. Что нужно сделать пользователю, чтобы выполнить некий бизнес-процесс с помощью вашего ПО. Много скриншотов, мало слов. Без этого документа пользователи будут регулярно по каждому чиху звонить в поддержку и (в особо запущенных случаях) в разработку. Надо ли говорить, что новому сотруднику без этого документа будет крайне сложно разобраться в прикладном ПО предприятия, которое, как правило, не отличается легкостью и интуитивной понятностью интерфейса?

6. Руководство системного администратора. Крайне необходимый документ, описывающий, какие ресурсы нужны прикладному ПО, как это ПО настраивать и как в нем раздавать привилегии и права. Документом пользуются как сисадмины, так и техподдержка (это не везде одно и то же подразделение). Без этого документа ваше ПО рискует в самый ответственный момент остаться без ресурсов (ядра CPU, место на диске). Также возникнет куча проблем со своевременностью раздачи прав: если информация в голове у двух человек, один болеет, другой в отпуске, то, чтобы сотруднику получить нужные привилегии, придётся недельку подождать. Неделька — это очень большой срок для бизнеса. Для бизнеса даже час слишком долго.

Понятно, что в этой статье рассмотрены далеко не все документы, сопровождающие процесс разработки от появления необходимости в чем-то до реализации этого чего-то на производстве. Я вообще не затронул область управления проектами, а в этой области документация — это основа основ. Я не описал все документы разработки и тестирования. Но, надеюсь, я убедил вас (неужели есть люди, которых надо в этом убеждать?) в том, что техническая документация — это крайне нужная и полезная вещь, которой ни в коем случае не стоит пренебрегать при разработке ПО.

Пишите документы!

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Поставлены ли в вашей компании процессы составления и обновления (актуализации) технической документации?

Поделиться публикацией

Комментарии 34

    +1
    Вот здорово бывает, оказывается. А у нас в компании в одной компании, где работает SWIM, почему-то разработчикам не дают ни ТЗ (пункт №1), ни ПМИ (пункт №4). Этот самый SWIM принимает участие в разработке всех остальных элементов документации, но, судя по всему, если бы документацией никто не занимался бы — с точки зрения руководства ничего бы не изменилось. :(
    Советовать SWIMу менять место работы?
      +2
      Разработчики же разные бывают, и процессы строятся по-разному.
      Руководство и не должно волновать наличие документации. У руководства иные задачи и цели (и их масштабы).
      Если SWIM'у кажется, что его чрезмерно грузят, но уровень компенсации не соответствует загрузке — пусть он обсудит это со своим руководством.
      Насчет смены места работы — SWIM'у виднее :)
      +2
      Дайте угадаю, для госструктур проекты делаете?
        0
        Интересно, с чего вы взяли? :)
          +2
          Так чиновники только в листах разговаривают. Другого языка у них нет. Потому эти тз которые мне попадались в сети большой воды гон, который как бэ и что то описывает но разабатывать по нему все равно не возможно. ТЗ — самоцель в работе с госструктурами.
          0
          Я там подобных вещей в качественном виде не часто встречал
            0
            Даже в качественном виде расписанном до мелочей разве возможно разобраться в (от) 200 листах? Поместить это в голову? Мне кажется бывает так, что наступает момент, когда разработка перетекает в разработку самого документа для разработки.
            0
            Нет. Я ниже написал.
            0
            Кто-нибудь пишет LLD?
              0
              Мне кажется, что больше похоже просто на описание API
                0
                Внедряем у себя Design Specification. Оно подразумевает достаточно подробное и низкоуровневое описание того, что будет делаться до реализации. После написание, делается review, возможно, выбирается более оптимальный вариант реализации.
                Проект достаточно зрелый и со сложной исторически сложившейся архитектурой. И очень не хочется, чтобы она неконтролируемо усложнялась и дальше. Чтобы упорядочить этот процесс всем правкам, влияющим на архитектуру системы, должен предшествовать Design Specification.
                И заодно документация пополняется, правда, еще не совсем понятно, что с ней делать дальше.
                +1
                Так сложность не в том чтобы документировать, а в том, чтобы документ успевал обновляться за разработчиками.

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

                Не могу рассматривать составление документации без плотнейшего общения в комманде на всех уровнях.
                  +2
                  А вы попробуйте наоборот — разрабочик не пишет код, пока в документацию не внесет описание того, что ему предстоит делать :)

                  Даже руководство пользователя можно написать раньше софтины (при наличии хорошего проектировщика и адекватного технического писателя). Такое руководство становится отличнейшей спецификацией для программеров!
                    0
                    ахах) ну вобщем то по другому он код писать и не сможет если не знает чо) Как показала моя не очень большая практика, программисту лучше дать дизайн проекта, интерфейс, чем тз.) Глядя на это он сразу врубается. Больше чем перечисление функционала, без строгой конкретики и точных деталей у меня не получалось составлять сопроводительные листы для разработки.

                    Все настолько плавает, пересматривается, упрощается, очевидится, что пункты или объединяются или лишние или я просто некомпетентен писать ему детали. Он знает лучше порой. Есть дизайн и необходимый функционал по пунктам, для того чтобы ничего не забыть.
                      0
                      Все зависит от уровня программистов, разумеется. Тех-лид получает на руки ТЗ, его подчиненные — написанные тех-лидом спецификации (например, так).
                    0
                    Я лично придерживаюсь концепции «договоров». Я пишу документ с подробным описанием функционала, который мне необходимо реализовать, с учетом взаимосвязей с остальной системой.
                    После этого отдаю этот документ человеку, который согласовывает и подписывается под ним (комментарием в wiki с указанием версии документа, под которой он подписался). Это позволяет разграничить ответственность между разработчиком (мной) и бизнесом, ставящим задачу и отвечающим на вопрос «как это должно работать с точки зрения пользователя/внешней системы?».
                    А когда есть четкая граница ответственности, человек более внимательно относится к тому, что в его зоне, и не оставляет на самотек.
                    Это не решает проблему синхронизации документации, но позволяет иметь актуальную на какой-то момент доку. А дальше, отталкиваясь от нее, с кодом в голове и VCS в руках можно достроить. А если много достраивать — самому же проще поправить доку и пересогласовать. В итоге схема становится самодостаточной.
                    И при этом она не требует участия всех. Даже если кто-то упорно не хочет писать документацию — она все равно появляется, потому что другим так проще жить.
                      0
                      Я знаю, что процессы разработки везде построены по-разному.
                      Но могу сказать, что я сам видел, как при правильной постановке процесса подобные случаи просто перестают происходить.
                      Ну, например, при нормально поставленном процессе разработки ПО программисту просто не попадают задачи, которые до того не обросли всеми необходимыми документами. Более того: безо всех нужных документов задача просто не будет поставлена в план работ команды разработки, как минимум по той причине, что без этих документов тим-лид будет просто не в состоянии оценить трудоёмкость задачи. Никто на себя такую ответственность не возьмёт.
                      Любой подошедший непосредственно к разработчику руководитель проекта, пытающийся давить авторитетом и кричать на тему «мне надо срочно вчера чтобы было у заказчика» будет обоснованно отправлен в пешее эротическое путешествие, ибо такого рода требования никогда не бывают реально оправданы ничем, кроме факапа самого РП. Все реально срочные потребности, ломающие составленные и всеми согласованные планы, проходят через повышение приоритета задачи до наивысшего только руководством компании. Которому для подобного повышения приоритета РП должен назвать ОЧЕНЬ веские причины.
                      Поэтому в коде не происходит никаких внезапных изменений.
                      Далее, после выхода кода от программистов, результат не отправляется сразу заказчику. Будет проведено тестирование, как функциональное, так и регрессионное (чтобы убедиться, что от изменений не умерло то, что уже работает). Если доработки касаются межсистемного взаимодействия, то будет проведено и интеграционное тестирование. Все сопровождается документами, и изменения, если надо, коснутся и пользовательской документации: без нее задача просто не пройдёт приёмку у заказчика.
                        0
                        Для того, чтобы компания могла себе все эти чудеса позволить нужны ровна одна вещь: captive market. То есть всё правильно читатели просекли: это либо госзаказ, либо махровый enterprise, либо военные. Vendor lock-in и все его прелести.

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

                          Это не captive market, а обратная ситуация: это заказное ПО.
                      +2
                      В каждой большой организации есть свои подходы. У нас проект начинается с маркетинговой спецификации (Marketing Functional Specification), где описывается общая функциональность с маркетинговой точки зрения, затем уже пишутся общие требования на ПО (Software Requirements Spec), затем дизайн (Design Requirements Spec). Архитектура, диаграммы развёртывания и т.д. либо являются частью SRS/DRS, либо выделяются в отдельные доки — это зависит от размера проекта. При внесении изменений в существующий проект также иногда создаётся документ с полным анализом изменений и рисков (Impact Analysis). Ну и для тестов тоже пишутся доки ессно. Иногда нас «пробивает» и мы делаем это в HP Quality Center (это дело молодёжь в основном любит), но я — программист «старой закалки» и предпочитаю по старинке, «ручками» — ну не люблю я автогенерированные документы. Документация важна для продуктов с длинным циклом. Иногда бывает надо внести изменения в продукт 10-15 летней давности — и тогда такие доки очень помогают, особенно для вновь прибывших программистов.
                        0
                        Если не секрет, вы в какой области софт разрабатываете?
                          0
                          Не секрет, конечно. Это программное обеспечение для промышленных систем рентгеновского неразрушающего контроля (как визуального, так и автоматического, причём в реальном времени).
                        +3
                        Перечисление этих гор потребной документации навевает грустные мысли. Я даже не знаю где работает топикстартер (банк? госструктуры? что-то военное? огромный консорциум где программисты — лишь небольшая часть всей структуры?), но это точно не контора где результат деятельности программистов решает — выживет она или нет.

                        Почему? Потому что через всю структуру красной нитью проходит СВЕРХЗАДАЧА: сделать так, чтобы «некто» (надо полагать обладающий властью и распределяющий денежные потоки внутри компании?) мог понять что происходит без открывания исходников.

                        Никакой другой цели в коллекционировании всех этих видов разнообразных бумаг нету.

                        Да, там где программисты общаются с внешним миром документация нужна и важна, нужны какие-то mockup'ы и карандашные наброски. Но это именно должны быть наброски. Желательно — крандашом на бумаге. Или фломастером по белой доске (с прикреплением их к краткому документу, описывающему ситуацию). Упаси вас бог создавать красивые mockup'ы в Phtotoshop'е — заказчик попросту решит, что всё уже готово и вы потеряете кучу нервных клеток.

                        Там же, где документация пишется для программистов большая часть описанного в статье не нужна. Да, нужен некоторый вводный курс, какие-то пояснения про то, как устроен проект и где в коде можно обнаружить те или иные места. Да, именно так: основным и самым важным компонентом документации является код. Он же тоже написан на некотором языке (будь то C++, Java или PHP), так почему вы не воспринимаете его как часть документации? Там ведь и высокоуровневая архитектура где-то существует, и низкоуровневая и тесты в каким-то виде отражены…

                        Это как с созданием литературного произведения: все, я надеюсь, писали сочинения? Вначале вы составляете план, потом делаете некоторый скелет, «набросок», потом пишите текст. Даже если результирующее произведение огромно (повесть или роман) общий объём всех этих вспомогательных документов не будет так уж велик — скорее у вас будет куча фрагментов и набросков, которые по той или иной причине не вошли в окончательное творение. Ну так у программистов для этого всего есть системы контроля версий! Там хранятся эксперименты, наброски, там вы можете (в отдельной ветке, скорее всего) попробовать прикинуть как можно переделать архитектуру и т.д. и т.п.

                        Руководства пользователя же… если честно я ещё не видел «сферических пользователей в вакууме», которые их читают. В большинстве случаев большое и основательное руководство пользователя — даром выкинутые деньги. Напишите лучше howto, которые бы проясняли как сделать то или иное действие. Как установить ваш продукт, как в нём сделать какие-то нетривиальные операции, etc. Если оказывается, что howto начинает состоять из нескольких десятков страниц — остановитесь, вернитесь к коду и измените его так, чтобы howto стал меньше: вам станет проще его писать, а пользователям станет легче его читать и количество обращений в техподдержку тоже уменьшится.

                        В общем как-то так. Конечно бывают и просто компании, в которых полный бардак и которые «на ладан дышат», но если вы пришли в компанию, которая успешно как-то обходится без всех этих гор бумаг и при этом зарабатывает неплохие деньги, то это — повод остановиться и задуматься на тему того как это происходит и почему работники этих компаний как-то без всего этого обходятся. Посмотрите хотя бы сюда: много вы тут обнаружите LDD или ПМИ? А ведь это проект, в котором участвуют сотни (а может и тысячи) разработчиков и где количество commit'ов измеряется сотнями в день!
                          +1
                          Обычно над проектом, хоть немного крупным, работают далеко не одни программисты. Да и программисты могут быть специалистами в совершенно разных областях и в разных языках. Пишете проект на C++ и привлекаете к нему специалиста по Oracle, а потом за дело берутся DevOps… будете предлагать им всем читать код?

                          Что касается руководств пользователей… посмотрите на полки любого книжного магазина — учебников по различному софту там сотни, каждый издан тысячами экземпляров. Почему кто-то их пишет и издает? Потому что изучить софт по руководствам от разработчиков не получается и люди идут покупать сторонние произведения.
                            +5
                            Вы не правы.

                            Я работал много лет в фирме, где всё это в ходу, а процесс разработки ПО отлажен, как конвейер по сборке автомобилей на современном заводе. ПО очень сложное и тяжёлое (порядка 20 схем оракла, аналогичное количество взаимодействующих между собой весьма сложных подсистем типа он-лайн биллинга или системы учета сетевых ресурсов): поддержка полного цикла работы оператора сотовой (а сейчас и фиксированной) связи. Если слышали слово FORIS OSS — то это оно самое. В год выходит несколько основных версий (релизов) с расширенным фукнционалом + несколько минорных версий со срочными доработками и (чтоб два раза не вставать:) ) с исправлением некритичных багов. Критичные до заказчика уже как лет 5 не доезжают — с тех пор, как было внедрено всестороннее и многоэтапное внутреннее тестирование.

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

                            Руководства пользователя — это именно how-to. Про изменение кода позабавило:) Вы поймите, речь идёт не об автоматизации работы ООО «Рога и копыта» (левый 1С + хакнутый MS Office), а о серьезном, тяжёлом прикладном ПО, обеспечивающем работу огромного территориально распределённого предприятия с миллионами клиентов и тысячами партнёров. Сотни программистов, миллионы строк кода, 7-разрядные номера рабочих элементов в MS TFS. Без документации, сопровождающей каждый этап, работать просто нереально. Но при этом — непосредственно программисты заняты этой «бюрократией» минимально. Не программист пишет эти документы, не программист общается с заказчиками, не программист пишет руководства пользователя и администратора, не программист сдает функционал заказчику. Программисты занимаются только своей непосредственной работой — пишут программы.

                            Есть компании, где процесс построен иначе. Не всем подходит такая схема работы: она весьма дорогостоящая, и применять ее для небольших проектов — означает стрелять из пушек по воробьям. Но даже если всё делает 5 человек — некоторые вещи стоит документировать просто для самих себя. Безусловно, процесс ради процесса это плохо, и строить такое — означает похоронить проект.
                              0
                              Плюс-плюс-плюс!
                              Но прошу заметить, что обычно проблемы всегда с фиксацией требований, внешних API и требований к окружению.
                              Поэтому их нужно документировать.
                              А вот внутренний дизайн проекта, подходы, стандарты кодирования и т.д. — для этого не нужны документы.
                              Либо за этим следит сама команда разработчиков, либо создает автоматизированные средства контроля, если в этом есть необходимость. И нет никакой необходимости это документировать — обучение путем работы в паре намного эффективнее. При этом код пишет новичок, а матерый программист просто объясняет, что делать, и отвечает на вопросы.
                              Как-то так.
                              Если кто не согласен — готов обсудить. Только аргументированно, пожалуйста — холивары ни к чему хорошему не приводят.
                              :-)
                                0
                                Внутренний дизайн проекта, подходы, стандарты кодирования и т.д. — IMHO должны разрабатываться один раз, потом им просто все следуют. Да и не такие они и объёмные.
                                А документы нужны для того, чтобы вновь пришедший сотрудник быстро въехал, как здесь принято, например, именовать переменные, и не приставал по ерунде к матерым программистам :)
                                  0
                                  Как именовать переменные обычно сразу видно из кода, разве не так? :-) А форматирование — современные IDE давно уже научились импорту/экспорту настроек.
                                    0
                                    всяко бывает :) бывает, что писали кто во что горазд… в итоге можно было встретить имена типа аааа1 или eto_eschyo_odna_moya_peremennaya, а чуть ниже — eto_eschyo_odna_moya_peremennaya_temp :)
                                      0
                                      В этом случае документация уже не спасет. :-)
                                      Хотя, возможно, спасение есть в модульных тестах и рефакторинге.
                                      При условии, что код рабочий.
                                      Если же код не рабочий — выкинуть и переписать заново.
                                      Так говорил Мартин Фаулер, и я с ним полностью согласен.
                                0
                                А не могли бы вы пояснить где именно я неправ? Потому что судя по вашему описанию всё ровно так как и ожидалось: махровый enterprise, заказчики не желающие (и/или не умеющие) общаться с программистами (но при этом всецело определяющие задачи!), полное отсуствие конкуренции, богатые заказчики, готовые платить за это (== за то, чтобы получить ровно то, чего им хочется). Это довольно узкая ниша. ERP и военные — вот и всё, пожалуй. Ну может ещё NASA и что-то подобное.

                                В большинстве компаний всё построено иначе. Неважно что ты делаешь — пишешь игру, разрабатываешь web-сайт, процессор или новую OS, в любом случае фактор времени для тебя является критичным. Если начать создавать все эти горы бумаг, то конкуренты тебя обойдут и ты обанкротишься. Ибо, как вам ни покажется удивительным, но продукт не вполне соответствующий тому, что нужно, с ошибками и недоработками, но вышедшый на полгода раньше выигрывает. А значит всё «лишнее» идёт под нож — в первую очередь ненужная документация. Только в тех случаях когда заказчик не может перескочить к конкуренту за полгода вы можете позволить роскошь описанную в статье.

                                Посмотрите на Microsoft: связав, как им казалось, своих клиентов по рукам и ногам они принялись внедрять процессы, подобные описанным вами. Результат мы видим: Windows Phone, Windows 8.x — это ведь всё оттуда.
                                  +2
                                  Я никак не пойму, в чем вы пытаетесь меня уличить или обвинить :)

                                  Вы неправы в своём понимании места документации в процессе разработки ПО: вы считаете документацию чем-то второстепенным. Но описанное в статье — не роскошь, а суровая необходимость при разработке и поддержке жизненного цикла любого «тяжелого» программного продукта. Просто попытайтесь представить себе продукт, которому для развертывания необходимо порядка 50 серверов, объдиненных в фермы и взаимодействующих друг с другом. Представили? А теперь представьте, что таких комплексов в России — 6. И они друг с другом тоже взаимодействуют. Никто не сможет удержать в голове такие объёмы функционала и тонкостей его реализации. Нет ни одного человека, который знает про эту систему ВСЁ. Ну да, это энтерпрайз. Махровейший. Дорогущий. Который может под нагрузкой полностью сожрать ресурсы нафаршированного по самое не могу HP DL 980 G7. И что?

                                  Безусловно, документирование не должно быть ради документирования. Если вы считаете, что документирование вам вообще не нужно — ОК, это ваш выбор. Никто ж насильно не заставляет. Если вы считаете, что отсутствие документации увеличивает вашу конкурентоспособность — я не буду вас переубеждать. Вполне может быть, что вы в вашем случае правы.

                                  Удачи.
                              0
                              У нас документирование через страдание :)
                              Задал клиент в техподдержку вопрос которого в документации нет — пишется статья, клиенту даётся ссылка (только на минимальной подписке).
                              В результате вполне такая юзабельная документация для сисадминов вышла.
                                0
                                Как правило этот путь проходит любая система с более-менее налаженным сопровождением.
                                Потому что предугадать вопросы клиентов часто представляется невозмжоным, а одиночные ответы иногда и нет смысла описывать — проще объяснять.
                                А вот когда объясняешь уже в третий раз — повод задуматься над автоматизацией процесса.

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

                              Самое читаемое