"Дефрагментация мозга. Софтостроение изнутри" - заметки на полях

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

На протяжении книги Сергей несколько раз повторяет тезис Брукса «хороший программист, на порядок производительней среднего». Тезис многократно подтвержден и в моей практике. Но как и Брукс, Сергей обошёл анализ факторов, которые влияют на производительность программистов, и, как следствие, вопрос о том, как отличить хорошего программиста от среднего. Или, если посмотреть на проблему с другой стороны, как стать хорошим программистом? Для меня, как архитектора и руководителя проектов (РП), этот вопрос представляет большой интерес, т.к. не в последнюю очередь, результат проекта зависит от тех, кто будет реализовывать решения, описанные в тех. проекте. Программисты любят списывать все проблемы проекта на кривую постановку, но это только половина правды.

За мою карьеру я поработал с 4-5-ю по настоящему высококлассными программистами. Далее буду называть их Программист. Факторы, повышающие производительность программиста (под этим я подразумеваю не скорость написания строк кода, а скорость получения результата, готово для передачи в эксплуатацию):

  1. Глубокое знание используемых инструментов – языка, фрейворка, среды разработки. Знание не на уровне заученных приемов, преданных по наследству от предыдущих программистов, а такое, которое позволяет обосновывать выбор конкретных решений в рамках реализации поставленной задачи.
  2. Узкая специализация. Если Программист владеет навыками по .NET, он не возьмется за разработку сайта на Python. А если такая задача всё же будет поставлена, то Программист возьмёт достаточно времени на изучение нового инструмента (именно на изучение, а не на знакомство).
  3. Разработка полного алгоритма решения задачи на стадии изучения тех. задания. Состав процедур, классы, объекты БД, события и т.д. продумываются до того, как будет написана первая строчка. Программист, на своём уровне, проектирует реализацию и только после этого начинает писать программу.
  4. Самоконтроль. Программист сам, как минимум, проверяет как в полученной реализации, обрабатываются все исключительные ситуации, которые он предусмотрел на стадии проектирования реализации.
  5. Постоянное повышение квалификации и углубление знаний. Если Программист обнаруживает пробел в знаниях, то он не использует первое посланное Богом Гуглом решение, а изучает проблему и выбирает оптимальное обоснованное решение.

Как РП может понять, что он имеет дело с Программистом:

  • Вы послали Программисту ТЗ, и через адекватное время на чтение и анализ он пришел к Вам со списком вопросов и уточнений. Таких итераций может быть не более 3-х.
  • На вопрос «Как продвигается реализация?» Программист называет сколько процедур, методов, объектов ему осталось отладить. Средний программист обычно отвечает, что осталось сделать пару функций, потребность в которых возникла в ходе реализации.
  • В ходе приёмки работы, вы беситесь, потому что придраться не к чему. В итоге просите переставить параметры в экранной форме местами, что бы было «по фен-шую».
  • Программисты редко посещают семинары и конференции – им там скучно.
  • Вы ненавидите своего коллегу, потому что ему нужен Программист, который работает в вашем проекте.

Я пришёл к выводу, что при тестировании кандидата, нужно давать не сложное, а «хитрое» задание. Задание, в котором заложено внутренние противоречие (придумать такое задание не просто, но если получиться, то на «эту блесну можно ТАКУЮ рыбу поймать»). Допустим контрольное время решения 1 час. Если чрез 10-15 минут, кандидат начинает задавать вопросы и намекать на ошибку в задании, стоит присмотреться к нему по внимательней. Если в конце контрольного времени, кандидат говорит, что почти всё работает, но надо отладить 2-3 особых случая, то это типичный средний программист. Думайте сами, решайте сами, кто вам нужен.

Большая часть книги посвящена ООП. У меня с изучением ООП не сложилось, мысли после знакомства с C++ у меня были как у девушки (Кошмар!!! У меня женская логика!), описанной в главе «Эволюция аппаратуры и скорость разработки» на стр. 42 – зачем всё это нужно?

Я не смог осилить ни Страуструпа (сломался где на 50-й странице), ни Буча (страница 20-я где-то). Те не менее я был воодушевлен и ожидал появления библиотек прикладных классов (документ, инвойс, накладная, склад и т.д.) из которых можно было бы конструировать приложения. А дождался классы – подключение к БД, список, квадрат, окно. Для меня ООП – обманутые надежды и разочарование. Одним из мотивов создания Ultima-Seller было желание восполнить этот пробел…

Долгое время я считал, что отсутствие в моём багаже теоретических знаний по ООП является ограничением. Но, оказывается, никакой теории нет. Спасибо Сергею, он снял с меня проклятие ООП.

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

С одной стороны Сергей критикует «птолемеевские системы» (субъективные системы, зависящие от точки зрения проектировщика), с другой стороны – оказывается книга в магазине, не то же самое, что книга в библиотеке. Далее на стр.130 он исправляется и помещает объекты одного класса «книга» в разные контейнеры. Чем может смутить читателя.

Книга, она, как говорится, «и в Африке книга». Этот класс обладает устойчивым набором атрибутов (Автор, Название, Издательство, Код, …) и свойств (Написать, Издать, Рецензировать, Цитировать, …). Обобщаться книги могут с другими печатными изданиями, но для этого нужны основания вытекающие из конкретной задачи. Магазин или Библиотека это контейнеры для классов «Товар» и «Единица хранения». А эти классы уже будут посложнее, потому что внутри должны содержать ссылку на объекты разных классов и предоставлять интерфейс к атрибутам и свойствам эти классов. Товарами могут быть – книга, открытка, журнал. Единицы хранения – книга, журнал, газета, грампластинка, микрофильм, рукопись.

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

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

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

Удивило заявление Сергея, что с версии SQL Server 2012 MS объявил ODBC основным (родным) API к СУБД. Ссылки на прессрелиз или документацию не дано. Не буду сейчас обсуждать, что последние время техническая политика MS напоминает флюгер. ODBC по определению не может выступать в роли «родного», т.к. реализует API на доступ к слою хранения данных, который не зависит от конкретной СУБД. Поэтому по стандарту ODBC поддерживает SQL в стандарте 1992 года. Расширения Transact-SQL через этот API не доступны.

В главе «Гибкость или наживулька» Сергей делает вывод, что какой методикой не пользуйся, сложность программы/проекта растет до тех пор пока не превысит способности программиста. Выше головы не прыгнешь? Но ведь очень хочется. 2 возможных способа:

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

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

  • с языками моделирования беда - стандартов нет. Самых языков, пригодных для описания модели в CASE системах тоже не много. В итоге у каждой «программной фабрики» своя нотация для описания модели.
  • сам процесс проектирования остается сплавом ремесла и искусства, в котором результат зависит от верховного шамана проектной команды.

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

Кризис ИТ отрасли (Сергей это отмечает в книге) связан с тем, что эпоха индустриализации в ИТ ещё не наступила, а квалификация бойцов ИТ фронта уже снижена и их подготовка поставлена на конвейер. Но Сергей так увлечён идей MD и программных фабрик, что в конце накидал лозунги новой индустриальной эпохи ИТ. Часть этих лозунгов, таких как «программные фабрики повышают производительность в 50 раз», оставляю на совести автора. Но мимо такого (стр. 194) «Наконец, для генерируемого кода не нужны тесты.» я пройти не могу. Ведь книга может попасть в руки детям!

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

Отдельное спасибо за главу про Ultima-Seller. Я практически проигнорировал тему на этапе подготовки книги. Причина видимо в том, что эмоционально это история «неудачного проекта». Прочитать в конце главы «история продолжается» было очень приятно.

Комментарии

Изображение пользователя Serguei_Tarassov.

Уточнения

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

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

Несколько уточнений.

Вот ссылка на денонсацию OLE DB и провозглашение ODBC "родным" для доступа к SQL Server. Я, конечно, согласен, что ODBC не может быть "родным" по определению, о чём писал в соответствующей главе. Добавлю только, что драйвер Microsoft имеет нестандартные расширения, позволяющие использовать все особенности SQL Server. Благодаря чемуQuery Analyser и позднее Management Studio, точнее её часть, управляющая запросами, работает именно через ODBC (иногда проскакивают знакомые сообщения).

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

Пример из наиболее близкой тебе области. Код генерируемый по модели БД из PowerDesigner или ERwin не требует тестов, включая шаблонные триггеры и хранимые процедуры. Однако любая рукописная процедура, использующая сгенерированные таблицы, виды и процедуры требует тестирования.

Изображение пользователя ipanshin.

по поводу генерации кода

Хочу сказать, что генераторы кода появились чуть ли не одновременно с самими компиляторами языков. Вспомните, что последняя фаза компилятора - это как раз генератор. При создании Юникс ядра использовался генератор. PAGEN (не помню как расшифровывается) тоже генератор. Современные факты: система DocsVision использует генератор объектов базы данных. Сервер приложений платформы 1С использует генерацию запросов к серверу баз данных. Ну и т.д.

Я не видел ни одного ПРОГРАММИСТА, который бы хотел что-то добавить к результату работы генератора. И правильно. До конца результат работы любого генератора не известен и этот путь приводит к ошибке.

Изображение пользователя Serguei_Tarassov.

Первый кодогенератор

Первый кодогенератор, по всей видимости, это макропроцессор (макроассемблер). Примерно 1950-60-е гг. Принципиальное отличие от рассматриваемых систем в книге - отсутствие формальных моделей в основе. Далеко не всякая кодогенерация является модель-управляемой разработкой.

Изображение пользователя ipanshin.

Вот один из

Вот один из вариантов продолжения: http://bisinteh.ru/nexus_invent.html

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

Прочитав выкладки о ПРОГРАММИСТАХ я начинаю сомневаться (в себе) и задавать вопрос, как тот руководитель группы (туристической), который забыл свой позывной,: "База, база а я кто?". На что база отвечает "Дура, ты". Кто такой программист? К примеру, кто-то набирает аутистов, которые считаются лучшими на эту роль из всех претендентов.

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

Мужик останавливает такси.
Таксист: "Куда вам?"
- "Нет, к удавам я не поеду".
- "Вы неправильно поняли. Куда вам надо?"
- "Ну, раз надо, тогда поехали к удавам".

Я склоняюсь к тому, что любой код (программный) в этом мире давно уже написан. Правда, язык может отличаться от языка BASIC, C++ или piton, etc. Я имею в виду тот мир, который нас окружает и к которому я все больше возвращаюсь, из мира программ или интернета, который создал человек. И Создатель этого программного кода вовсе не человек, а некая высшая сущность ( или Бог). Человеку отведена роль гораздо более скромная, чем Творец. Он является только ПРОВОДНИКОМ тех идей, знаний, наконец, воли, которые несут абсолютную сущность. И эта сущность прежде всего существует независимо от человека, она - истина. Поэтому чем меньше привносится программистом искажений в эту сущность, тем она ближе к идеалу. То есть здесь я хочу сказать, что программист - не технический человек, вовсе не технарь, а понимающий прежде всего природу вещей.

Раскидало так, что не собрать
Дни, места, желания и страсти
Будем Я и Ты перебирать
В памяти, что было в нашей власти.

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

В памяти струящейся от брызг,
Что могло бы вовремя случиться -
Я бы, как собака, время грыз
Чтоб другим туда вновь возвратиться!

Изображение пользователя Serguei_Tarassov.

Еще рецензии

Еще рецензии на книгу:
от Павла Грибанова: http://reeders.livejournal.com/170346.html.
от Сергея Бобровского (по его обзорам я по сути входил в мир КИС в середине 1990-х): http://www.pcweek.ru/idea/blog/idea/5177...
добрые люди не поленились процитировать фрагменты из книжки на форуме Оберона: http://zx.oberon2.ru/forum/viewtopic.php...