Никто не выясняет прирост эффективности компьютерной отрасли
относительно общества в целом. Потому что если попробует
выяснить, то наверняка обнаружит, что она падает и может быть,
уже выражается отрицательным числом, поскольку области, в которых
эффективность положительна, перевешиваются областями, в которых
от компьютеров больше потерь, чем пользы.
Компьютерная отрасль берётся помогать всем организовываться,
хотя она не в состоянии органзовать саму себя. Поэтому получает-
ся, что она по большей части поставляет в другие области деятель-
ности не свои средства поддержки организации, а свой абсурд.
Если использовать сложные программные средства, то к сложности
предметной области прибавляется сложность этих средств, а доверие
к ним тем меньше, чем они сложнее, потому что с ростом сложности
увеличивается число ошибок и в программных средствах, и в
использовании этих средств.
Увеличение сложности программного продукта должно допускаться
лишь тогда, когда оно даёт увеличение эффективности в широком
смысле, а не только облегчает всучивание этогопродукта покупате-
лям при том состоянии их мозгов, какое имеет место в настоящее
время после интенсивной многолетней обработки абсурдизирующей
рекламой.
В развитии технических средств существует как тенденция
усложнения, так и тенденция упрощения: отказа от излишних,
неуместно применяемых сложностей, замены сложного простым.
Новое buzz-word -- это новый товар, новая возможность заполучить
деньги клиента. Всякое новшество должно какие-то проблемы решать
и какие-то создавать: если не будет решения проблем, то трудно
убедить клиента, что продукт ему нужен; а если не будет создания
новых проблем, то не будет и возможности продать следующее
новшество.
Когда чешется затылок, можно просто почесать его. А можно
реализовать метод "почесать" объекта "правая рука", наследующего
объекту "рука", который, в свою очередь, наследует объекту
"конечность", наследующему объекту "часть тела". Простые вещи
можно делать и простым, и сложным образом, сложные -- только
сложным, иначе запутаешься.
Умение обходиться без сложностей не менее, а то и более
значимо, чем умение с ними работать.
* * *
Чем чётче выдержаны архитектурные принципы в программной систе-
ме и чем единообразнее её код, тем проще в этой системе что-то
поменять.
Характер устанавливаемого технологического порядка должен
соответствовать характеру выполняемой работы, в противном случае
этот порядок будет выглядеть абсурдным, и его вряд ли станут
поддерживать в полной мере.
Чем более сложна разрабатываемая система, тем более развитой и
жёсткой должна быть система правил согласования усилий в процессе
совместной работы. Если система правил согласования недостаточно
развита, разработчики создают много проблем друг другу и самим
себе.
Технологический порядок на большом проекте должен быть "священ-
ной коровой": от него нельзя отступать, но можно его совершенст-
вовать. Отступления от технологического порядка привлекательны
какими-то локальными и быстрыми выгодами но в конечном счёте они
ведут к неоправданному усложнению программной системы и стиуации
вокруг неё. Иногда удаётся завершить проект до того, как нараста-
ющая масса сложностей сделает продвижение вперёд невозможным,
иногда не удаётся.
И руководители проекта, и рядовые исполнители должны работать
без спешки и перегрузки: необходимо, чтобы было время на анализ
своей работы и ситуации вокруг неё, на генерирование идей, выходя-
щих за рамки решения текущих проблем. Спешка и перегрузка вредны,
среди прочего, тем, что провоцируют нарушения технологического
порядка.
Работа над проектом должна вестись на двух уровнях: на уровне
решения проблем этого проекта и на уровне развития представлений
о том, как надо работать над проектами такого типа вообще. По-
следнее полезно не только для будущих проектов, но и для текуще-
го, поскольку позволяет применять опыт пройденных его этапов при
прохождении последующих. Если не предпринимать целенаправленных
усилий по развитию обобщённых представлений о способах выполнения
работы, а рассчитывать на то, что опыт "отложится" сам собой,
следующий проект будет реализован не намного лучше текущего, а
конечный этап работы над текущим проектом пройдёт не намного
лучше начального.
* * *
Компоненты экранного диалога:
1) простой ввод данных;
2) проверка допустимости типа вводимых данных;
3) проверка полноты вводимых данных;
4) выбор из списка или проверка наличия в списке;
5) проверка взаимного соответствия данных;
6) формирование новых данных на основе введенных и
предложение их для проверки и/или модифицирования;
7) экранное представление данных в основной форме (целостное
представление записей одной таблицы);
8) экранное представление данных в производной форме (частичное
представление записей одной таблицы, представление
взаимосвязаных записей нескольких таблиц);
Первые четыре позиции в этом списке могут обеспечиваться сред-
ствами СУБД, седьмая позиция -- посредством простой утилиты,
входящей в комплект средств СУБД.
Часть пользовательского диалога может быть обеспечена посред-
ством утилит СУБД.
Под все формируемые и используемые на предприятии данные можно
создать таблицы в базе данных (взаимосвязанные через внешние
ключи) и обеспечить к ним ЭЛЕМЕНТАРНЫЙ ДОСТУП в многопользова-
тельском режиме посредством утилит СУБД.
Можно создать коллекцию SELECT-ов для формирования на основе
этих данных любых отчётов, не требующих сложной предварительной
обработки данных и их сложной перекомпоновки.
Далее при этой базе данных можно создавать (в одном стиле и на
основе одной системы прототипов) множество любых приложений,
обеспечивающих более сложный ввод-вывод данных, а также обработку
данных, то есть формирование новых данных на основе имеющихся.
Можно создать ориентированную на малоподготовленного пользова-
теля настраиваемую программу для простой ручной работы с таблица-
ми базы данных: ввода, вывода, отбора по указанным признакам,
перекомпоновки экранного представления и пр. На основе этой
программы можно быстро создавать не очень сложные приложения,
которые в очень многих случаях будут достаточными.
Можно многое эффективно сделать даже просто на основе файловой
системы, то есть без использования СУБД.
* * *
Опасности в процессе разработки программной системы:
1. Утрата стройности.
Невыполнение или неправильное выполнение системой некоторых
действий может быть следствием 1) неполноты архитектуры,
2) ошибок в архитектуре, 3) ошибок в реализации архитектуры.
Решать проблемы типов 1, 2 можно посредством переделки архи-
тектуры, проблемы типов 1, 2, 3 -- посредством локальных
изменений в устройстве системы. Такие локальные изменения
называются заплатами (patches). Когда заплат оказывается
слишком много, наступает утрата единообразия в устройстве
частей системы и понимать и корректировать работу системы
становится очень сложно. Возможность фундаментального развития
архитектуры утрачивается, и внести изменения в функционирова-
ние системы обычно удаётся лишь посредством добавления очеред-
ных заплат -- поверх уже имеющихся.
2. Утрата единства стиля.
Одну и ту же архитектуру можно реализовывать очень по-раз-
ному -- как в отношении деталей алгоритма, так в отношении
оформления программного кода. Если разные части системы реали-
зуются разными людьми, не стремящимися к одинаковости решений,
эти части приобретают очень разный вид и знание устройства
одной из них уже не может значительно облегчить работу с
другой.
3, Утрата человеческого масштаба.
Даже при полном сохранении стройности системы и единства
стиля её частей сложность системы может оказаться такого
уровня, что для решения проблем в системе придётся удерживать
в голове одновременно такое количество фактов, которое
значительно превышает средний объём человеческого внимания и
кратковременной памяти, так что оперировать этими фактами
становится практически невозможно.
Заплаты в программном коде (то есть изменения вне рамок
архитектурной схемы) дозволительны только в двух ситуациях:
1) когда требуются очень срочные исправления (в дальнейшем эти
заплаты убираются, а вместо них модернизируется архитектурная
схема);
2) когда срок эксплуатации системы близок к завершению.
Если ведётся борьба с заплатами, то при любой заплате должен
быть комментарий, указывающий, к какому типу заплат она относит-
ся, кем и зачем поставлена и на какой срок.
Заплаты бывают:
1) временные:
в ожидании уточнения некоторых требований;
в ожидании переделки архитектуры;
заменяющие фрагмент кода, разработка которого отложена
ради более быстрого получения работающего варианта
программы для её демонстрации или для проведения некоторых
экспериментов;
2) постоянные:
для компенсации дефекта, исправить который не получается
из-за того, что не удаётся локализовать его причину или
придти к единому мнению с коллегами;
для того, чтобы не переделывать архитектуру.
Возможное оформление комментария к заплате:
1) PATCH temp. by AAAA since DD.MM.YYYY till (ожидаемое событие);
2) PATCH const. by AAAA since DD.MM.YYYY to (цель).
Если постепенно наращиваемый программный код в некоторой части
системы получается путанным, без простой очевидной структуры, он
нуждается в радикальной переделке. Его следует расматривать как
макетный вариант, предназначенный для уточнения потребностей и
возможностей перед разработкой того варианта кода, который войдёт
в систему. Необходимость отказа от ущербного варианта кода возни-
кает тогда, когда наращивание и корректировка кода становятся
довольно сложными, а до завершения работы по наращиванию его
функционалитета ещё далеко.
* * *
Программирование -- области деятельности, которая быстро обнов-
ляется, поэтому, чтобы удержаться в ней, программисту необходимо
регулярно наращивать свои знания, то есть уменьшать свои твор-
ческие возможности и нейтрализовывать свой профессиональный опыт.
В настоящее время широкий специалист -- тот, кто знает много
частностей из разных специальных областей и которого можно
переводить с одной "низовой" работы на другую. Между тем, нужны
широкие специалисты, которые умеют работать на уровне абстракций,
не порывая с реальностью. При нынешнем состоянии мозгов
"низовики" смотрят на редких доморощенных "стратегов" как на
философствующих бездельников, которые избегают настоящего дела,
чтобы скрыть свою некомпетентность, а "стратеги" на "низовиков"
-- как на профессионально изощрённых недоумков, которые блестяще
делают зачастую ненужную работу и создают проблемы друг другу и
следующим поколениям.
* * *
Неоправданное разнообразие сущностей (объектов, их атрибутов,
операций над ними) в компьютеризуемой области и их частое измене-
ние -- одна из причин сложности и низкого качества программного
обеспечения.
Компьютеры существенно облегчили операции с данными и докумен-
тами, но это привело не к повышению качества управления, а к то-
му, что люди воспользовались возможностью увеличить разнообразие
управляемых сущностей, так что качество управления осталось при-
близительно на докомпьютерном уровне, если и вовсе не понизилось.
Можно сказать, компьютеры провоцируют на усложнение компьютеризу-
емых областей деятельности, потому что издержки от усложнения не
отягощают ту или иную область, а переносятся в другую -- в
область компьютеризации, которая, в свою очередь, уже ставится
перед фактом усложнения, а кроме того, является модной, "прогрес-
сивной" и многообещающей, так что людям представляется, что эти
издержки будут иметь место только на первых порах или что они --
неизбежная плата за "прогресс", то есть, по сути, за то, чтобы
выглядеть передовыми в глазах всех.
Более сложное -- не обязательно лучшего качества. Мир вещей и
технологий усложняется зачастую неоправданно, без разумных осно-
ваний, не совершенствуясь относительно "первичных" показателей
его эффективности.
К примеру, банк организует принятие какого-то нового вида
вклада не потому, что старые виды вкладов страдают какими-то
недостатками, а потому что есть возможность привлечь клиентов
новизной, поскольку клиенты воспитаны на идеологии "прогресса",
то есть имеют подсознательную установку на то, что новое лучше
старого. Ещё одна причина появления нового вида вкладов -- то,
что отдел развития банковских услуг стремится себя проявить.
Между тем, новый вид вклада означает ряд изменений в документа-
ции, программном обеспечении и т. п., а также переучивание и
дополнительную работу сотрудников банка, которые будут этим видом
вклада заниматься. То есть, будут дополнительные затраты, которые
приведут в конечном счёте к тому, что проценты по вкладам и
зарплата банковских работников окажутся меньше, чем могли бы
быть. Вместо этого можно было бы законодательно ограничить разно-
образие видов вкладов и тем самым исключить конкурентную борьбу
банков в области демонстрации ненужных обновлений и перенаправить
усилия на уменьшение технологических издержек при оказании фикси-
рованных видов банковских услуг. Выгода от этого состояла бы ещё
и в том, что потенциальным клиентам банка не надо было бы затруд-
нять себя ознакомлением с новыми ненужными возможностями и тра-
тить время на сложный выбор между большим количеством вариантов.
* * *
Ещё одна причина низкого качества программного обеспечения --
прогресс в программировании: программисты не успевают вполне
освоить новые технологии разработки программ и вполне отладить
созданные с их помощью системы, как возникает необходимость осва-
ивать ещё более новые технологии и переделывать на их основе
системы, иначе эти программисты и их системы будут выглядеть
старомодными. Но даже если возникнет желание смириться со своей
старомодностью, из этого ничего не получится, потому что разра-
ботчики инструментальных средств перстанут их поддерживать, а
производители аппаратных платформ перестанут эти платформы по-
ставлять и ремонтировать. Замедлиться в своём "развитии" отдельно
от остальных невозможно: ты или бежишь в равном со всеми темпе,
или выпадаешь из толпы, из профессии, из бизнеса. Сбавить темп
этой всеобщей абсурдной гонки можно только реформированием ком-
пьютерной отрасли в целом, но она настолько мощная и соответст-
венно денежная, что сама способна "реформировать" любого, кто
будет мешать ей функционировать так, как она функционирует.
Чтобы заставить людей трезво взглянуь на ситуацию в целом, нужно
очень большое потрясение.
* * *
Если прототип для программной системы правильно выбран (или
специально создан), при её разработке искать решения тех или иных
технических задач почти не приходится: надо в основном размножать
те или иные отлаженные в прототипе решения. При возникновении
необходимости в новом техническом решении надо исследовать уже
отлаженный код системы на предмет наличия в нём готового решения,
которое можно заимствовать. При этом выгода получается не от
экономии сил, а от обеспечения единообразия кода. Если возникает
идея лучшего решения, чем то, которе уже реализовано в найденной
аналогичной ситуации, надо отказываться от неё либо добиваться,
чтобы это решение было применено в этой аналогичной ситуации --
вместо того решения, которое уже реализовано.
* * *
Надо стремиться к тому, чтобы на проекте ни одна проблема не
решалась дважды (тем более трижды и т. д). Чтобы избежать дубли-
рования, надо выделять и фиксировать решения, которые могут стать
типовыми.
На проекте должен вестись список правил написания и оформления
программного кода. Этот список может пополняться любым членом
группы разработчиков, столкнувшимся с новой ситуацией и выбравшим
некоторый способ действия в ней. Руководитель группы разработчи-
ков может изменять, дополнять, отменять предлагаемые таким обра-
зом правила. Правила становятся обязательными только после утвер-
ждения их руководителем группы разработчиков. Правила могут выно-
ситься на обсуждение в группе разработчиков по инцициативе любого
из её членов.
* * *
В бою лучший солдат -- не тот, кто храбрее других и метче дру-
гих стреляет, а тот, кто держит линию, прикрывает товарищей и
точно выполняет приказы. Аналогично в коллективной работе над
проектом лучший программист не тот, кто больше умеет и быстрее
других пришет код, а тот, кто соблюдает принятые на проекте пра-
вила, тесно взаимодействует с коллегами и точно следует установ-
кам руководителя проекта. От очень способных, но недисциплиниро-
ванных работников бывает больше вреда, чем пользы: они нарушают
правила ради каких-то локальных выгод и этим ухудшают качество
системы в целом, а также создают конфликтные ситуации внутри
коллектива и в отношениях с заказчиком, чем затрудняют работу над
проектом. И их трудно переубждать.
В отношении нарушения правил наиболее опасны для проекта инди-
виды следующих типов: 1) молодые, да ранние; 2) страдающие кризи-
сом среднего возраста; 3) разболтанные. Первые характеризуются
избытком самоуверенности, не сдерживаемой опытом, и стремлением
поскорее проявить себя вопреки всему. Вторые побуждаются к отча-
янным поступкам хронической неудовлетворённостью своими жизненны-
ми достижениями. Третьи вообще не имеют склонности к соблюдению
правил.
* * *
В коллективе программистов более способные индивиды склонны
выступать командные игроки либо как индивидуалисты. Индивидуа-
лист, обнаружив или освоив что-то новое, не стремится поделиться
своим знанием с коллегами, потому что это потребовало бы затрат
времени и уменьшило бы его превосходство. За счёт полученного
преимущества он начинает тянуть на себя работу, приобретает
возможность ещё больше расширять свои познания и тем самым
увеличивает свою ценность, хотя команда в целом при этом,
возможно, даже слабеет. Командный же игрок, вырвавшись в чём-то
вперёд, старается подтянуть за собой других.
* * *
Нередко излишние сложности, излишнее многообразие, небрежно
оформленный и не вполне отлаженный код производятся сотрудниками,
чрезмерно стремящимися проявить себя на фоне менее активных
коллег. Такие люди торопятся застолбить побольше участков и не
любят подстраиваться под других членов команды. Они выглядят
очень продуктивными, лучшими из всех, но их усилиями закладывают-
ся основания будущих проблем. Если создаваемая система имеет
сравнительно невысокую сложность и работа над нею длится не очень
долго, эти выдающиеся специалисты не успевают много наследить, и
проект заканчивается до того, как порождаемые ими проблемы
проявятся и обострятся. Но если создаваемая система сложная,
увеличивается опасность того, что проект вообще не будет доведен
до успешного конца.
* * *
Можно писать программные модули быстро: не очень стремясь к
единообразию, не очень задумываясь об именах компонентов и о
качестве комментариев, не тратя сил на документирование сделан-
ного и т. д. В этом случае программист выглядит производительным,
то есть хорошим специалистом. Правда, в его модулях много ошибок
и эти ошибки трудно искать.
Можно исправлять ошибки быстро: добиваясь, чтобы исчезали
только те нежелательные эффекты, по которым эти ошибки были
обнаружены, и не выискивая аналогичных ошибок в других местах, не
устраняя причин подобных ошибок, не комментируя свои изменения и
не корректируя соответственно документации. В этом случае про-
граммист тоже выглядит производительным, то есть хорошим специа-
листом. Правда, поток обнаруженных ошибок ослабевает медленно, а
после каждого значительного изменения в системе испытывает боль-
шой всплеск. Поскольку вносимые в код исправления плохо именованы,
плохо комментированы и плохо документированы (если как-то пояс-
нены вообще), то более или менее разобраться в них может только
сделавший их специалист, который становится таким образом и
вовсе незаменимым.
Этому выдающемуся специалисту начинают поручать наиболее
сложную разработку и исправление наиболее сложных ошибок. Он всё
лучше ориентируется в системе, и разрыв между ним и остальной
командой в этом отношении всё увеличивается. Всё больше оказыва-
ется заданий, с которыми способен справиться только он, из-за
чего он работает со всё увеличивающейся перегрузкой и его решения
становятся всё более торопливыми и поверхностными, а команду раз-
работчиков системы сокращают на несколько человек.
Если создаваемая система не очень большая, то вполне возможно,
что этот выдающийся специалист доведёт её до конца: не загнав её
в какой-нибудь эволюционный тупик и не сломавшись сам. Система
будет иметь требуемый функционалитет, правда, окажется медленна и
неудобна в работе, трудна в сопровождении и неказиста на вид.
Обычно в выдающиеся программисты выбиваются индивиды с хорошей
памятью и развитым формальным мышлением, не склонные обобщать, не
отягощённые творческими амбициями в области программирования, но
очень любящие ходить в лучших и, возможно, также склонные пере-
шагивать при случае через других.
* * *
Можно говорить о существовании женского стиля в программирова-
нии. Особенности этого стиля определяются тем, что женщины, как
правило, обладают хорошей памятью не мелочи, но не склонны мыс-
лить стратегически. Женское программирование -- это случайные
названия переменных, минимум комментариев, обилие "заплат" и,
как следствие, -- сложность (для мужского ума) ориентирования в
программном коде.
* * *
Разработчик, решивший проблему, с которой могут столкнуться и
другие разработчики его группы, должен письменно сообщить им всем
об этой проблеме и о её решении. Это полезно, среди прочего, тем,
что он получает возможность быть своевременно поправленным.
* * *
Названия компонентов системы должны в возможно большей степени
отражать назначение этих компонентов. Чем тщательнее это обеспе-
чивается, тем меньше потребность в различных справочных таблицах
и комментариях, требуемых для того, чтобы выяснять по названию
компонента его назначение, по назначению -- название.
Если в какой-то части системы принять некоторый порядок обозна-
чения некоторых компонентов, то во всех других частях системы
должен быть принят по возможности точно такой же порядок обозна-
чения тех же компонентов: это избавляет от необходимости зани-
маться "переводом" с "языка" одной части системы на "язык" другой
части системы при переключении внимания от одной части к другой.
* * *
В названиях подпрограмм, переменных и т. п. должно быть едино-
образие. К примеру, если где-то использовано ..-IN и ..-OUT, то
везде в аналогичных случаях должно быть ..-IN и ..-OUT, а не, к
примеру, ..-DOWN и ..-UP.
Для обеспечения единообразия должен использоваться словарь
сокращений. В этом словаре следует представлять не одну, а две
или три ступени возможных сокращений, например:
INPUT -> INP -> I
OUTPUT -> OUT -> O
Также должна быть единообразной схема посроения названий под-
программ. Например, ...-OOO-AAA, где OOO -- объект, по отношению
к которому совершается действие, AAA -- действие, которое совер-
шается по отношению к объекту.
Возможные действия:
INS (insert)
DEL (delete)
UPD (update)
MOV (move)
SEL (select)
CHK (check)
GET (get)
PUT (put)
и т. п.
Чем чётче, проще, информативнее система именования компонентов,
тем легче ориентироваться в программном коде. Хорошо, если все
подпрограммы и элементы данных, относящиеся к одному информацион-
ному объекту,имеют общий компонент в названии, облегчающий их
распознавание в качестве таковых.
* * *
Чем регулярнее структура программной системы, тем легче с нею
работать. На отклонение от регулярности надо идти лишь в исключи-
тельных случаях и лишь при условии, что невозможно вместо этого
изменить регулярность. Всякое отклонение от регулярности должно
быть снабжено комментарием, поясняющим характер отклонения и/или
его причину.
Регулярное иногда получается более громоздким, чем иррегуляр-
ное, но выигрыш при этом получается на этапе отладки системы, а
также в процессе её сопровождения и развития.
* * *
Если какие-то однотипные элементы кода располагаются рядом, их
размещение должно быть упорядоченным. К примеру, в алфавитном
порядке их названий. Этот порядок должен быть одинаковым во всех
местах системы, где располагаются рядом эти однотипные элементы.
Порядок облегчает ориентирование в коде и формальную проверку
кода на полноту.
* * *
Отладочная работа в процессе создания программной системы
должна иметь целью не столько устранение конкретных ошибок,
сколько внесение в архитектуру системы и в технологии её
разработки таких изменений, которые препятствуют появлению
ошибок и облегчают исправление тех ошибок, которые всё-таки
появляются. К примеру, если причиной ошибок является сходство
именований некоторых объектов, надо изменить эти именования.
* * *
Если обеспечен требуемый функционалитет программной системы это
значит ещё очень мало. Во-первых, она должна быть дружественной
пользователю (user-friendly), в том числе защищённой от ошибок
пользователя. Во-вторых,её программный код должен быть удобным
для сопровождения и развития. В-третьих, и код системы, и работа
с нею должны быть качественно задокументированы. Если эти условия
не выполняются, то более-менее сложная программная система оказы-
вается не пригодной к эксплуатации. Если система сложная, то в
случае пренебрежения этими условиями её даже вряд ли удастся
довести до способности выполнять в полном объёме предписанный
функционалитет, потому что при малой пригодности системы для
сопровождения и развития будут страдать в первую очередь сами её
разработчики в процессе её отладки и доработки.
...............................................................
...............................................................
Александр Бурьяк.