Опубликован: 17.06.2015 | Доступ: свободный | Студентов: 1616 / 131 | Длительность: 13:09:00
ISBN: 978-5-9556-0174-8
Лекция 4:

Принципы agile

< Лекция 3 || Лекция 4: 123 || Лекция 5 >

4.5 Технические принципы

Мы переходим к рассмотрению программно-специфических приемов, составляющих суть agile подходов.

4.5.1 Вести разработку итеративно

Разработка agile – это итеративная разработка. Аджилистам не хватает терпения на процессы, характерные для "водопадного" стиля – практикуемого или воображаемого, когда недели или даже месяцы отводятся на разработку требований и проектирование, прежде чем начнется создание кода. С точки зрения agile доказательством пудинга является сам пудинг – то есть код. Его нужно поставлять часто и как можно раньше.

Выполнять частые рабочие итерации
Итеративный подход – вертикальная декомпозиция

Рис. 4.4. Итеративный подход – вертикальная декомпозиция

Доводы в пользу итеративной разработки в литературе по программной инженерии приводятся давно, начиная со статьи Базили [Basili 1975]. Такая разработка может принимать различные формы. Итеративный процесс может, например, производить последовательные подсистемы или кластеры будущего продукта, каждый из которых фокусируется на технологическом слое, входящем в финальную систему. Здесь могут быть кластер живучести (база данных), сетевой кластер, кластер бизнес-логики, кластер пользовательского интерфейса. Такой итеративный подход можно называть "вертикальной декомпозицией".

Итеративный подход – горизонтальная декомпозиция

Рис. 4.5. Итеративный подход – горизонтальная декомпозиция

Но это не совпадает с понятием agile об итеративной разработке. Декомпозиция agile "горизонтальная" – каждая итерация должна представлять работающую систему.

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

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

Длительность итерации

Во всех agile подходах предполагается, что итерации должны быть короткими, типично – несколько недель. Они отличаются лишь конкретными сроками. Scrum называет итерации спринтами и часто (хотя это не носит универсальный характер) отводит четыре недели на спринт.

Я счел полезным в собственной разработке следовать рекомендациям Scrum, но в качестве срока спринта выбрал календарный месяц. Говорить "октябрьский релиз", указывая конкретный ключевой срок, просто и понятно – конец месяца. Разница в днях между месяцами несущественна. Фактическое время разработки всегда короче, поскольку требуется оставить время в начале и конце месяца на планирование спринта и подведение итогов – обзор спринта.

Такая итеративная разработка состоит из временных блоков: длительность итерации жестко фиксируется и не может изменяться. Если в конце отведенного времени окажется, что запланированная функциональность не полностью реализована – не соответствует критерию "сделано", то она либо переносится на следующую итерацию, либо удаляется, но контрольные сроки не изменяются.

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

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

Аджилисты иногда рассматривают природу временных блоков итераций как повод для отказа от одновременного выдерживания сроков и поставки требуемой функциональности в разворачиваемом релизе системы. Конечно, это не повод – внешние требования пользователя по-прежнему остаются. Анализ ошибочного мнения "либо что, либо когда" будет рассматриваться при обсуждении вопроса о переходе к agile.

Замораживание требований на период итераций

Методы agile, как мы знаем, выступают за "изменения", но в любом реалистичном подходе изменениями следует управлять. Здесь мы сошлемся на строгое правило Scrum: функциональность может быть добавлена только на фазе планирования спринта. Как только спринт стартовал и команда приступила к реализации выбранных функций, ничто не может меняться до окончания спринта. Запрет строгий, применяется ко всем в проекте и вне его, включая менеджеров.

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

Итеративная разработка. Оценка

Следует отдельно оценить каждую из двух рассмотренных идей – частоту итераций и требование замораживания спринта. Наиболее важное свойство частых работающих итераций в том, что они частые. За прошедшие десятилетия индустрия ПО уже поняла, что подход "Большого Взрыва", когда различные команды работают над своими раздельными частями проекта, а спустя несколько месяцев пытаются объединиться, не работает. Расхождения трудно фиксируются; люди делают несогласованные предположения об остальных частях системы, и позже их с трудом удается примирить. По этой причине Майкрософт ввела режим ежедневного построения системы, когда компиляция и запуск системы производятся каждую ночь (Build должен работать!). Если кто-то внес изменения, приводящие к ошибке, изменения отвергаются, а виновник, как правило, не прекращает работу, пока не исправит ошибку. Цикл разработки, основанный на разработке итераций, выпускаемых каждые несколько недель, становится повседневной нормой. В этом немалая заслуга подхода agile, популяризирующего эту идею.

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

Когда идет строительство дома, то долгое время застройщики мало что могут продемонстрировать будущим жильцам. Они работают над фундаментом, прокладкой коммуникаций, над всем тем, что гарантирует устойчивую жизнь дома. Каждое утро вы проезжаете мимо и думаете: "Черт возьми, что они делают все это время? Я совсем ничего не вижу!" Затем в один из дней вы замечаете нечто похожее на начало строительства дома, и с этого момента процесс идет удивительно быстро, поскольку настоящая основа была заложена.

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

Если все это происходит в Южной Калифорнии, следует ли думать о сейсмоустойчивости дома или отложим эту проблему для рефакторинга? Тем более что "пользователи" – будущие жильцы – о землетрясениях и не думали, последнее большое землетрясение было сто лет назад! Согласятся ли они с лозунгом YAGNI – "Вам Это Не Понадобится"?

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

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

Порядок задач

При любой итеративной разработке возникает вопрос, как в рамках итерации команда определяет порядок выполнения работ. XP был первым, кто дал ответ в agile: начинайте с "простейшей вещи, которая может еще работать".

Все agile подходы продвигают подобную идею. Кокбурн [Cockburn 2005], критикуя стратегию "Сложную Вещь – Первой", пишет:

[1] Если команда терпит неудачу при поставке системы, то у спонсора нет понимания причины неудачи. То ли команда не способна выполнить этот проект, то ли выбрана неверная технология, то ли процесс ошибочен? В добавление к этому члены команды могут начать спорить друг с другом и впасть в депрессию.

Он предлагает начинающим и опытным командам соответственно следующую стратегию:

[2] Команде, которая не работала вместе, столкнулась с новой задачей, с новой технологией, я предлагаю "Простейшую Вещь – Первой, Самую Трудную – Второй". Команда и спонсоры узнают вкус ранней победы. Если самая трудная задача превосходит возможности команды, то второй задачей должна быть трудная задача, с которой может еще справиться команда.

[3] Когда риск и вероятность технических ошибок уменьшится, то лучшей стратегией является "Важнейшую по Значимости – Первой".

Рекомендация [2] понятна. На ПО переносится очевидное наблюдение, что команда начинающих альпинистов не может начинать с Эвереста, а новый оркестр с "Весны Священной" Стравинского. Но выгоды предлагаемой стратегии относятся к команде, а не к проекту. Что если самая трудная вещь, отложенная вначале, вне возможностей команды? Тогда ранние успехи окажутся напрасной тратой сил, и ранний успех создаст обманчивое представление. В этом случае можно привести те же аргументы, что приведены в [1]:

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

Для сплоченной команды Кокбурн рекомендует стратегию [3] – начинать с наиболее значимой задачи. Это обычная agile рекомендация, характерная, в частности, и для Scrum. Такие рассуждения могут приветствоваться многими менеджерами, но стратегия может оказаться безответственной. Продукт успешен, если он предлагает не одно важное свойство, а совокупность поддерживающих свойств. За элементом с высочайшим приоритетом следует элемент с высоким приоритетом, и эта череда приоритетов продолжается. Что если первый по приоритету реализован великолепно, а остальные плохо? Начальное восхищение скоро сменится раздражением и недовольством.

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

Дуальная разработка

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

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

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

Плакат заключительных этапов дуальной разработки

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

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

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

Такую комбинацию подходов – последовательную или параллельную – мы называем дуальной разработкой.

4.5.2 Рассматривать тесты как ключевой ресурс

Стремление к созданию качественного продукта – сердце программной инженерии. Достаточно просто приводить доводы в пользу качества, значительно труднее найти способы, обеспечивающие это качество. Есть разные приемы в борьбе за качество, например, подход CMMI направлен на улучшение управления проектом. Другие способы являются техническими и включают, например, формальные (математические) методы спецификации и верификации. Для большинства в индустрии и для agile методов принципиальным техническим способом обеспечения качества является тестирование.

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

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

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

С другой стороны, нормальная реакция, по крайней мере, моя реакция, когда я слышу, что предлагается средство обнаружения ошибок: "Да! Ого! Дайте мне его скорее!" Конечно, мы хотим найти все "ошибки", до которых могут дотянуться наши руки.

Методы agile рассматривают тесты как основной ресурс каждого проекта. Ресурс, содержащий набор регрессионных тестов. В этот набор включаются все тесты, которые обнаруживали ошибку в некоторой точке проекта. Как следует из названия теста, целью является предотвращение феномена, известного как "регрессия", когда найденная и, казалось бы, исправленная ошибка вновь появляется в процессе дальнейших модификаций системы. Старые "баги" вновь появляются. Причины этого явления могут быть различными. Чаще всего исправление ошибки устраняет симптом, а не причину болезни. Пока причина болезни не будет устранена, ее симптомы могут проявляться снова и снова. Как бы там ни было, риск регрессии – одна из причин, по которой каждый проект хранит набор регрессионных тестов, включая в него каждый тест, обнаруживающий ошибку в любой точке проекта.

Развитие этой идеи поддерживается современным инструментарием, позволяющим программисту:

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

Эта комбинация функциональностей обычно называется "автоматическим тестированием". Данный термин является некоторым преувеличением, так как такое тестирование не покрывает наиболее тонкие и требующие временных затрат процессы генерирования тестов, описания оракула. Тем не менее, соответствующие инструменты, пионером среди которых был инструментарий JUnit, изменили практику программной разработки и сделали возможным акцент agile на необходимость включения в проект набора регрессионных тестов и запуска набора по нажатию одной кнопки.

Следующие два принципа расширяют эту фундаментальную роль тестов в мире agile.

4.5.3 Не начинайте новую разработку, пока не пройдут все тесты

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

Дилемма, знакомая каждому менеджеру, – список задач большой и только растет, но не все, что реализовано, корректно работает. Где взять ресурсы? В проектах agile решение принимает группа, а не отдельное лицо, но проблема все равно остается. Подход agile ясен: не идти дальше, пока не пройдут все тесты.

Подход похвальный, но жизнь иногда заставляет вносить коррективы в простые схемы. В частности, баг багу рознь (все жучки различны). Тест, который ломает систему, может выявлять серьезную проблему, так что дисциплина agile права: двигаться дальше не следует до решения проблемы. Но иногда в случае бага речь может идти о нарушении функциональности, не играющей важную роль в текущем состоянии. Удаление функциональности решает проблему, но удаление – деликатная задача, не только требующая времени, но и порой приводящая к появлению новых багов. Можно схитрить, изменить спецификацию и сказать, что это не баг, а функция, которая работает должным образом. Это не помогает в долгосрочном плане, так как корректная версия все равно понадобится.

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

4.5.4 Вначале создайте тест

Наиболее спорным принципом является идея создания тестов, предшествующих разработке, ассоциируемая с XP и применяемыми ключевыми практиками этого подхода – разработка, управляемая тестами, и разработка с предшествующим тестом. Мы еще подробно обсудим эти практики, а пока рассмотрим ключевую идею.

Идея принципа очевидна и следует из буквально понимаемых слов: "вначале создайте тест", то есть не пишите код, пока не напишете тесты, проверяющие корректность работы кода. В этом подходе тесты заменяют написание точных спецификаций – идея довольно естественная. Но в экстремальном программировании принцип "вначале тест" понимается более широко. Бек [Beck 2005] описывает это так:

Напишите падающий автоматический тест перед изменением любого кода.

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

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

Принцип "вначале тест", играющий важную роль в XP, является предметом серьезной критики, поскольку тесты заменяют спецификации, с чем не все согласны. Но хочется отметить важный вклад этой идеи agile: никакая функциональность не добавляется без предварительного написания теста, поэтому отсюда вытекает важное свойство таких проектов – нет кода без тестов.

4.5.5 Выражайте требования через сценарии

Agile отрицает необходимость "предваряющего анализа". Но разработка нуждается в требованиях и в подходах agile подчеркивается необходимость создания продукта, отвечающего пользовательским ожиданиям, поставляющего определенные ценности бизнесу.

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

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

Пользовательская история описывает элементарную единицу взаимодействия – с меньшей степенью гранулярности. Стандартная схема описания пользовательских историй (примеры появлялись ранее в этой главе), принятая в мире agile:

Как <роль я хочу <действие> для достижения <цель>.

Последняя часть может быть опущена. Например, при создании графической игры:

Как игрок я хочу, чтобы все части фигуры, приносящей выигрыш, мигали или подсвечивались, чтобы я мог видеть эту фигуру.

Далее будем использовать термин "сценарий" как для вариантов, так и для пользовательских историй.

Принцип использования сценариев для спецификации требований является широко используемой практикой agile и одной из наиболее опасных практик. Спецификации задают общее описание, варианты и пользовательские истории, как и тесты, специфичны. Десять пользовательских историй – это десять случаев, в которых отсутствует абстракция, характерная для спецификации. Если я скажу вам, что моя функция на входе 1 возвращает значение 1, на входе 2 возвращает значение 4, на входе 3 возвращает значение 9, на входе 4 возвращает значение 16, то я ничего не сказал о других значениях.

У меня был интересный опыт общения с графической программой, строящей по заданным значениям функцию, наиболее приближенную к введенным значениям. Помимо указанных значений, я задал еще точку (5, 25). К моему удивлению, помимо ожидаемого значения 36 для точки 6, возможными были значения 34 и 35,6. Подробности можно посмотреть в моем блоге [Meyer 2012].

С другой стороны, если бы я сказал вам, что моя функция f(x) это x2, то это была бы точная спецификация, снимающая все вопросы.

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

Типичный пример, с которым я недавно столкнулся, связан с владелицей небольшого бизнеса, которая общалась с пенсионной системой. Система позволяла построить пенсионный план либо для членов, либо для администраторов, а она была и тем и другим, что не предусматривалось сценариями.

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

< Лекция 3 || Лекция 4: 123 || Лекция 5 >
Алексей Задойный
Алексей Задойный

В главе "5: Роли agile" http://www.intuit.ru/studies/courses/3505/747/lecture/26297?page=2 есть упоминание:

Скримшир [Scrimshire сайт]

но нет адреса сайта. Укажите пожалуйста адрес в тексте лекции.

Или речь о человеке James Scrimshire?

Павел Плахотник
Павел Плахотник

http://www.intuit.ru/studies/courses/3505/747/lecture/26293

Сделайте пожалуйста вопросы более корректными. Это сложно конечно. Но надо четко понимать что именно имеется в виду.

По предварительному анализу, водопаду, документам требований вообще не понятно что имеется в виду. Возможно надо будет изменить авторский текст, но всё же ясность и конкретность важна. А её нет.

 

Игорь Васильев
Игорь Васильев
Россия, СПб