4.2. Компактность и ортогональность
Код не является единственным объектом, который имеет оптимальный размер своего элемента. Языки программирования и API-интерфейсы (например, библиотечных или системных вызовов) сталкиваются с теми же ограничениями человеческого восприятия, которые создают U-образную кривую Хаттона.
Следовательно, Unix-программисты научились весьма тщательно продумывать при проектировании API-интерфейсов, наборов команд, протоколов и других способов повышения эффективности два другие свойства: компактность и ортогональность .
Компактность — свойство, которое позволяет конструкции "поместиться" в памяти человека. Для того чтобы проверить компактность, можно использовать хороший практический тест: необходимо определить, нуждается ли обычно опытный пользователь в руководстве для работы с данной программой. Если нет, то конструкция (или, по крайней мере, ее подмножество, которое охватывает обычное использование) является компактной.
Компактные программные средства обладают всеми достоинствами удобных физических инструментов. Их приятно использовать, они не препятствуют работе, позволяют повысить продуктивность.
Компактность не является синонимом "слабости". Конструкция может обладать большой мощностью и гибкостью, оставаясь при этом компактной, если она построена на абстракциях, которые просты в осмыслении и хорошо взаимосвязаны. Компактность также не эквивалентна "простоте обучения". Некоторые компактные конструкции являются весьма сложными для понимания до тех пор, пока пользователь не овладеет сложной основополагающей концептуальной моделью настолько, что его мировоззрение изменится, благодаря чему компактность станет для него простой. Для многих классическим примером такой конструкции является язык Lisp.
Компактный не означает также "малый". Если четко спроектированная система является предсказуемой и "очевидной" для опытного пользователя, то она может иметь довольно много частей.
Кен Арнольд.
Очень немногие программные конструкции являются компактными в абсолютном смысле, однако многие являются компактными в более широком смысле. Они имеют компактный рабочий набор, подмножество возможностей, подходящее
для решения 80-ти или более процентов тех задач, для которых их обычно используют опытные пользователи. На практике для таких конструкций обычно требуется справочная карта или памятка, но не руководство. Подобные конструкции называются полукомпактными в противоположность строго компактным конструкциям.
Данная идея, возможно, лучше иллюстрируется с помощью примеров. API системных вызовов Unix является полукомпактным, однако стандартная библиотека С некомпактна в любом смысле. Тогда как Unix-программисты в своей памяти без затруднений содержат подмножество системных вызовов, достаточное для большей части прикладного программирования (операции с файловой системой, сигналы и управление процессами), библиотека С в современных Unix-системах включает в себя много сотен входных точек, например, математические функции, которые "не поместятся" в памяти одного программиста.
Статья "The Magical Number Seven, Plus or Minus Two: Some Limits on Our Capacity for Processing Information" [54] является одним из основных документов по когнитивной психологии (и к тому же особой причиной того, что в Соединенных Штатах местные телефонные номера состоят из семи цифр). Статья показывает, что количество дискретных блоков информации, которое человек способен удерживать в краткосрочной памяти, равно семи плюс-минус два. Из этого следует хорошее практическое правило для оценки компактности API-интерфейсов: необходимо ли программисту помнить более семи входных точек? Любую более крупную конструкцию едва ли можно назвать компактной.
Среди инструментальных средств Unix компактной является утилита make(1) , a autoconf(1) и automake(1) компактными не являются. Что касается языков разметки: HTML — полукомпактный язык, a DocBook (язык разметки документов, который будет рассматриваться в главе 18) таковым не является. Макросы man(7) компактны, а разметка troff(1) — нет.
Среди универсальных языков программирования С и Python являются полукомпактными, a Perl, Java, Emacs Lisp и shell — нет (особенно ввиду того, что серьезное shell-программирование требует от разработчика знаний нескольких других средств, таких как sed(1) и awk(1) ). С++ — антикомпактный язык — его разработчик признал, что вряд ли какой-либо один программист когда-нибудь поймет его полностью.
Читать дальше