Словарик философствующего информатика
Человеческая речь не только носит информацию, но также направляет мысли и действия людей. В науках иные термины и выражения обладают энергией почти волшебного свойства. Одно лишь слово «нейроэтология» в беседе с биологами вызывает волнение, — видимо, напоминая о неразрешённом споре. Подобные спорные понятия многи в каждой из наук: «тёмная материя», «скрытая переменная», «эмерджентность», «сложность», «семантическая сеть», «нейролингвистика», «синдром Аспергера», «экономическая социология», «бихевиоризм», «стволовые клетки», «этика», «справедливость»…
Энергия бывает не только волнующей, но также и объединяющей, умиротворяющей, вводящей ученых в ощущение понимания основ устройства Вселенной. Например, «принцип неопределённости», «преобразование Фурье», «теория категорий», «экономические циклы», «полнота по Тьюрингу», «аттрактор», «ещё по одной» и много других.
Это ключевые слова соответствующих наук, помогающие учёным понимать друг друга с полуслова и таким образом повышать уровень научного обмена. Специалисты думают этими словами, видят их во сне, ожидая озарения. Мера профессионализма порою измеряется именно числом известных данному человеку волшебных слов, с которыми он может с толком обращаться.
Так вот, мы стремимся собрать здесь слова, задающие философскую, интуитивно универсальную основу информатики.
Эти слова достаточно неожиданно всплывали из небытия и удивительным образом исполнялись смыслом. Они стали своебразными точками входа в храм философствующих информатиков. Конечно, будут встречаться слова и поприземлённее: азбучные концепции, полезные слова-связки — слова, которые из песни не выкинешь.
Введение
правитьУспехи в систематизации чего-либо нередко заслуживают внимания лишь медицинского. Однако, некая произвольная ассоциативная сеть понятий может весьма облегчить понимание темы, не навязывая при этом гипнотизирующего брильянта в виде единственно верной «объединяющей теории всего».
Так, мы стремимся составить словарик, описывающий некие документированные понятия:
- кратко и ясно;
- «Программному коду следует быть локально понятным.»
- в сопровождении важных, а потому немногих, ссылок:
- со ссылками на соответствующую статью в Википедии;
- без стремления к совершенно неоспоримой строгости и нейтральности определений и утверждений.
Критерии внесения термина в словарик:
- широкое применение без особых разногласий об определении;
- связь с актуальными проблемами и задачами информационных технологий;
- полезность для образования думающего информатика.
Почему не в Википедии?
правитьВикипедия, будучи толковой энциклопедией, стремится к контекстности и многоаспектности в своих описаниях понятий и явлений, то есть к снабжению каждого факта метафактом, а каждого примера контрпримером.
Это неизбежно ведёт к высокой структурности, сложности изложения. Читателю нетрудно запутаться в одном из бесконечных зацикливаний энциклопедической статьи на самых мелочных спорных моментах; заблудиться в трёх-четырёх соснах, чьих ветвей тернистые фракталы не дают увидеть леса за деревьями.
Очевидно также преимущество Викиучебника в свободе стилевого выбора. Нестрогий стиль иногда предпочтительнее, ибо строгими и однозначными понятиями иногда нельзя описать разнообразный и неоднозначный мир.
Об авторах
правитьЗамысел такого словаря витал в воздухе. На страницах Википедии и Викиучебника встречаются тексты по информатике, в которых делаются попытки коротко написать о многом. Затравку из первых 20 понятий сделали Николай Николаевич Непейвода и Артём Викторович Ворожцов. Часть текстов была взята из Приложения «Идеология» викиучебника «Ruby» (по материалам книги «Программист-прагматик» Эндрю Ханта и Дэвида Томаса.)
Со временем, надеются авторы, словарик совместит труды по созданию упрощенного, но ценного, достаточно целостного, но не доведенного до обессмысливающей систематизации понятийного тела информатики.
Структура словарика
правитьПоначалу намереваемся всё писать на одной странице. Потом, вероятно, будем раскрывать некоторые термины в отдельных статьях, связывая всё гиперссылками.
Базовые понятия
правитьПредмет информатики
правитьИнформатика образовалась спонтанно при овладении человеком искусства автоматического вычисления, и с умопомрачительным, беспрецедентным успехом развилась в современную академическую дисциплину, исчадия которой включают в себя почти что всех главных богатеев планеты.
Вычисление же само по себе может изучаться, а так или иначе лежит в основах, — математики, глубокую и объединяющую суть которой пока не объяснили даже физики с философами.
В теоретической части это математика, но с припаянной к ней кнопкой Гёдель-стопа, а также загорающимся на самом интересном месте табло: НУЖЕН БЫСТРЕЕ КОД.
Прикладной же смысл информатики — в составлении правил, пардон, технологий обращения со сложностью: вычислительной, колмогоровской, игровой, инженерной, термодинамико-статистической… сенсорно-когнитивной… экономической…
Характерный внешний вид — вид свалки умирающих технологий — прикладная информатика принимает, среди прочего, из-за рекурсии: порою наиболее сложными по своей природе оказываются сами технологии. Изучение оных постфактум представляет законченное, наукоподобное описание предметной системы, а также дает пути упрощения, либо же поступательного усложнения.
Ещё одна — не фундаментальная, но на практике характерная черта информатики — это преобладание дискретных данных, соответственно, — цифровых вычислительных устройств. Учёный, достигший редкого мастерства аналогового программирования, наверное, изучал параллельно информатике физику или что-то подобное, избежав «чистую» математику. Если тот учёный родился на свет, то если бы он написал целостный основной учебный текст, то информатика выглядела бы совершенно по-другому, притом оставаясь информатикой. Однако, скорее всего, его еще на ранних подходах перевербовали в какую-нибудь военную авионику. Двадцатый век.
Но полно! Как же нам серьезно определить информатику? Видимо, наиболее близким к сути будет такое описание-определение:
Информатика — это наука о методах формализации, обработки и организации больших объемов информации.
Смысл эпитета «больших» здесь несёт качественную нагрузку.
Формализация
правитьФормализация — это строгое описание (процесс создания описания) чего-либо с целью использования этого описания в деле. Так, например, химик создает описание вещества в виде химической формулы. По этому описанию химик-практик может предсказать свойства вещества и сконструировать его из ингредиентов.
Формализация чем-то похожа на поэзию. Поэт, как ни странно, загоняя себя в рамки строгих правил построения стихотворной формы, может выразить больше и с большей убедительностью, чем писатель прозаик.
А в информатике правила еще строже. Требуется, чтобы описания понимал не только человек, но и цифровое устройство.
Архитектура компьютера. Вычислимость и вычисления
правитьПараллелизм
правитьПараллелизм — исполнение, при котором разные блоки программы исполняются одновременно. Различают истинный параллелизм, когда разные вычисления идут на разных исполнителях действительно одновременно, и квазипараллелизм, когда один и тот же исполнитель выполняет несколько вычислительных процессов, и ощущение одновременного исполнения эмулируется с помощью переключения исполнителя между процессами.
Одной из важных проблем является извлечение пользы из параллелизма в условиях тонкого (медленного и/или ненадёжного) информационного канала между исполнителями.
Параллелизм делится на И-параллелизм, когда для успеха должны завершиться все подпроцессы, и ИЛИ-параллелизм, когда достаточно успешно завершиться одному из них.
Логически параллелизм естественно возникает в событийном и функциональном программировании. Но, в принципе, он реализуем на базе различных стилей (парадигм) программирования.
При распараллеливании программы необходимо держать в уме одновременно и её логические, и её ресурсные характеристики, и (зачастую абсолютно несообразную) структуру конкретного параллельного оборудования. Все это, вместе с хакерским характером нынешних систем поддержки параллельного программирования, делает распараллеливание исключительно трудной областью, где еще лет двадцать понадобятся специалисты с задатками хакеров.
Программирование. Языки программирования
правитьАлгоритм
правитьАлгоритм — предписание, которое может быть формально исполнено и в результате приводит к решению задачи.
Конкретных вариаций формального понятия алгоритма имеется множество (машины Тьюринга, алгоритмы Колмогорова и как их частный случай алгоритмы Маркова, рекурсивные схемы, RAM машины и т. п.) Все эти понятия математически эквивалентны, но сложностные характеристики при решении разных классов задач могут различаться принципиально. Эти формализации становятся приципиально различными, если мы рассматриваем относительную вычислимость (алгоритм, базирующийся на процедурах, которые считаются заданными внешним образом) или вычислимость над объектами высших типов (см. тезис Чёрча).
Из «Потенциала»:
Автоматное программирование
правитьАвтоматное программирование — стиль программирования, при котором вычисление ориентируется на структуру конечного автомата: программа представляется как совокупность состояний, каждому состоянию программы или переходу в ней может быть сопоставлено глобальное действие, изменяющее состояние вычислительной системы, переход к новому состоянию осуществляется по результатам анализа характеристик измененного состояния системы.
Автоматное программирование (называемое в FP программированием от
состояний) наиболее адекватно тогда, когда действия глобальны, а условия
локальны. Оно может быть реализовано множеством способов (программа,
интенсивно использующая go to
, система объектов, в
которой каждое конкретное состояние описано как наследник общего объекта
«состояние программы», и т. п.) Оно требует, чтобы конкретные
локальные действия и описания были упрятаны в реализации процедур,
изменяющих состояние системы, поскольку автоматное программирование
глубоко концептуально противоречит, в частности, структурному.
Концептуальные противоречия между автоматным и сентенциальным
программированием намного менее резкие.
Автоматное программирование имеет два варианта: последовательный, когда система неделима, и остается лишь совладать с широким пространством состояний программы, и параллельный (асинхронный), когда систему можно разбить на подсистемы, и каждая подсистема действует относительно независимо. Варианты могут реализовываться одним из двух методов: когда действия сосредоточены в состояниях или когда они выполняются на переходах между состояниями.
Моделирование
править«исследование объектов познания на их моделях; построение и изучение моделей реально существующих предметов, процессов или явлений с целью получения объяснений этих явлений, а также для предсказания явлений, интересующих исследователя.»
Информатик иногда занимается созданием компьютерных моделей реальных объектов. Но важно отметить, что термин «модель» в информатике обозначает уже некую самостоятельную сущность, не привязанную ни к какому реальному объекту. Конечно, часто существует некоторый моделируемый реальный объект, но его может и не быть. Реальный объект может быть физическим объектом во плоти (вычислительное устройство, сеть компьютеров, промышленный завод или его части, …), или опять же виртуальным, как и сама модель (программа, база даннных, информационная система, …).
Важно отметить, что в практике разработки сложных систем создание модели всегда идёт перед созданием самого объекта. Модели в информатике не моделируют существующее, а предшествуют разработке нового. Например, создание модели хранимых данных и модели информационных потоков является важным моментом на этапе проектирования информационных систем.
Итак:
Модель — это формализованное описание чего-либо, то есть чётко и однозначно определяющее и, (в идеальном случае) интерпретируемое компьютером, описание на некотором формальном (строго определённом) языке.
Метамоделирование — это одновременно и процесс и некоторая методология (идеология), провозглашающая, как нужно правильно моделировать. Это методология формулируется достаточно просто: «прежде чем создавать модель, придумайте модель описания моделей». Модель описания модели называется метамоделью. В результате имеем трехуровневую систему: метамодель, модель, сам объект. Наличие метамодели гарантирует некоторую гибкость системы — возможность быстрой адаптации системы в случае необходимости изменения модели. Модель не заложена в самую основу системы, а может меняться пользователем системы в пределах, позволяемых метамоделью.
Концептуальность
правитьКонцептуальность (или концептуальная целостность) — один из главных критериев качества модели (программного средства, программного модуля, системы, …). Определяется полнотой и целостностью математических принципов, заложенных в основу модели.
Как и всякая философская концепция, концептуальность является одной стороной некоторого баланса. Ему противостоит концепция «прагматичности при получении нужного функционала»:
Рассмотрим два полюса:
- Концептуальная целостность и чистота принципов, заложенных в основу (математической теории, стиля программирования, …).
- Эклектичность, смешение различных принципов, необоснованность структуры.
Очевидно, что следует стремится к первому. Но при этом нужно не забывать о народной мудрости и принципах человека-прагматика:
- «при пожаре по кратчайшему пути в ближайшую дверь»
- «не бейте из пушки по воробьям»
- «золотые горшки не нужны»
- «и так сойдет»
- «кто платит, тот и музыку заказывает»
- «лучшее — враг хорошего»
Причиной забвения и непопулярности некоторых моделей (языков программирования, технологий, программ) является именно их излишняя концептуальная целостность. Но это редкость. В основном же, программное обеспечения страдает отсутствием концептуальной целостности и наличием концептуальных противоречий. Это связано с конечностью сроков разработок, отсутствием профессиональных человеческих ресурсов, несовершенством потребностей пользователей (требований заказчиков).
Имитационное моделирование
правитьМетод изучения систем, когда система представляется программой, внешнее поведение которой подобно внешнему поведению изучаемой системы. Критерием качества имитационного моделирования является близость поведения моделируемой и моделирующей системы при не очень большой сложности модели.
Пионером имитацонного моделирования можно считать Клавдия Птолемея. Он отказался от мысли найти силы, вызывающие движение планет, а просто построил вычислительную модель (первую из известных в истории достаточно сложных программ), описывавшую доступные ему наблюдения с помощью метода, который намного позже получил название рядов Фурье. В дальнейшем имитационное моделирование послужило одним из идейных оснований аналоговых машин, когда процессы одной физической природы моделировались процессами совершенно другой (например, механическое движение электрическим током или миграция людей — потоками воды). В настоящее время мы вернулись к уровню Птолемея, и основным инструментом имитационного моделирования служат программы.
Нормативное моделирование
правитьНормативное моделирование — метод изучения систем, когда система представляется идеей, а внешнее поведение системы комбинацией идеи и корректив, вносимых конкретной ситуацией. Критерием качества нормативного моделирования является предсказательная сила: возможность его переноса на ранее не изучавшиеся случаи. Точность представления поведения системы является вторым приоритетом, более того, для построения качественной нормативной модели обязательно нужно чем-то пренебречь.
Нормативное моделирование является основным методом изучения мира со стороны богословов. Блестящими примерами нормативного моделирования явились работы Галилео Галилея и Исаака Ньютона (законы механики были сформулированы для инерциальных систем, которых в природе не существует), Г. Менделя (законы наследственности были открыты на уникальном примере растения и признака, где наследственные факторы выделялись в чистом виде; практически всегда они не являются чистыми и подвержены действию окружающей среды и других наследственных факторов) и Р. Вольтерра (построившего модель «хищник-жертва» на основе идеи обратных связей в природе и тем самым заложившим основы теории экологического равновесия). Менее удачным, но весьма показательным, примером нормативного моделирования является теория эволюции Ч. Дарвина
Неформализуемое понятие
правитьНеформализуемое понятие — понятие, смысл которого зависит от контекста и меняется таким образом, что противоречит любой его формализации. В жизни это такие понятия, как любовь, добро, в математике — теория множеств (как её ни формализуй, обязательно найдется необходимое для математических построений свойство, которое не выполнено).
Формализация неформализуемых понятий является одним из основных видов деятельности современной цивилизации. Только формализовав понятие, мы избавляемся от сомнений и можем локально успешно действовать. Но как только мы забываем о «локальности» любой успешной формализации, мы попадаем в глобальный тупик. Поэтому для любой, особенно для успешной, концепции необходима альтернатива. Более того, даже сложные формальные понятия (например, определения языков программирования) человек воспринимает как неформализуемые.
Концептуальное противоречие
правитьКонцептуальное противоречие — термин теории неформализуемых понятий, обозначающий формально непротиворечивые понятия либо концепции, мешающие друг другу при совместном использовании. Первым явно осознанным примером концептуального противоречия явилось противоречие между структурным и автоматным программированием. Отсутствие понимания самой идеи концептуального противоречия является основной бедой современной науки и практики, особенно в информатике. Большие системы просто разваливаются под грузом концептуальных противоречий.
Разработка программного обеспечения
правитьХарактеристики программного средства
правитьХарактеристики программного средства делятся на группы. Характеристики, важные пользователю:
- функциональность (functionality)
- надёжность (reliability)
- лёгкость и удобность применения (usability)
- эффективность (efficiency)
- мобильность (portability)
Функциональность — это способность ПС выполнять набор функций, удовлетворяющих заданным или подразумеваемым потребностям пользователей. Набор указанных функций определяется во внешнем описании ПС.
Надёжность — это когда ПС поставили на военную технику, а его разработчик спит спокойно.
Лёгкость применения — это характеристики ПС, которые позволяют минимизировать усилия пользователя по подготовке исходных данных, применению ПС и оценке полученных результатов, а также вызывать положительные эмоции определенного или подразумеваемого пользователя.
Эффективность — это отношение уровня услуг, предоставляемых ПС пользователю при заданных условиях, к объему используемых ресурсов. То есть, скорость и точность работы (или актуальность и полнота услуг, предоставляемых ПС), деленное на вычислительную мощь исполнителя.
Мобильность — это способность ПС быть перенесенным с одной платформы на другую, то есть возможность использования ПС на разных устройствах с разными операционными системами. Сегодня это, в первую очередь, возможность использования на мобильных устройствах.
Функциональность и надежность являются самыми важными характеристиками ПС, причём обеспечение надежности красной нитью проходит по всем этапам разработки ПС. Остальные критерии имеют меньший приоритет и ранжируются в зависимости от типа ПС и потребностей пользователей.
Но для разработчиков важна другая характеристика ПС:
- Сопровождаемость — это совокупность свойств ПС, которая позволяют минимизировать усилия по внесению изменений для устранения в нем ошибок и по его модификации в соответствии с изменяющимися потребностями пользователей.
Эта характеристика касается не качества работы ПС, а качества архитектуры и качество исходного кода ПС:
- концептуальная продуманность архитектуры, которая делает систему простой, легко понимаемой и расширяемой
- самодокументированность кода
- самопроверяемость кода
Эта характеристика, часто не принимаемая во внимание пользователем (пользователь часто просто не имеет доступа к исходным кодам ПС), играет ключевую роль в жизнеспособности и используемости ПС на практике.
Есть и другие характеристики ПС. Важно на этапе проектирования ПС определится с ключевыми характеристиками, расставить приоритеты и соответственно с ними спроектировать ПС и организовать разработку ПС.
Сложность
правитьСуть вопроса — неизбежность сложности. Методы борьбы со сложностью:
Модульность. Разбиение ПС на модули — наборы процедур (алгоритмов, объектов), выполняющих связанную функциональность. Если программисту нужно обратиться (проанализировать, изменить) к некой реализованной функциональности, то он откроет конкретный модуль, который реализует эту функциональность. Снижается сложность для анализа.
Обеспечение независимости модулей системы. Если в одной части функциональности происходят изменения, а она тесно связана с другой функциональностью (явным образом использует сущности, предпосылки, связанные с изменившейся функциональностью), то по ПС прокатится «волна изменений». Необходимо будет анализировать и изменять не один модуль, а несколько связанных. Если же заранее сделать модули независимыми, то потребуются изменения только в конкретных интерфейсах модулей (местах передачи входных параметров для функциональности модуля). Снижается сложность для изменений.
Повторное использование. Если алгоритм успешно реализован в одной части ПС, а затем требуется в другой части, то хорошо бы использовать уже реализованное, изменяя лишь отдельные входные параметры алгоритма. Можно заранее выделить функциональность, сделав её универсальной. Снижается сложность замены функциональности.
Использование иерархических структур. Если группа сущностей имеет одинаковые свойства (поведение), то общую часть можно заранее выделить в отдельную сущность, реализующую универсальные алгоритмы. Снижается сложность создания новых сущностей (адаптации системы).
Подпорка
правитьПодпорка — объект, понятие или конструкция, вводимая лишь для того, чтобы уложить алгоритм решения задачи в прокрустово ложе конкретной системы.
Например, подпоркой может называться кусок кода, в котором осуществляется обработка не предусмотренного архитектурой системы случая. Типичные подпорки — «обертки» для использования внешнего API. Такие куски кода обычно много занимают места, но мало делают.
Подпорка не имеет никакого отношения ни к сущности задачи, ни к существу алгоритма её решения, но сложность требуемых подпорок может существенно повлиять на выбор не только способа реализации алгоритма, но и самого алгоритма. Для успешной перестройки программы необходимо четко отличать подпорки от существенных деталей и не пытаться разобраться в их тонкостях, а заменять их в первую очередь.
Причин возникновения подпорок две:
- отсутствие концептуальной целостности архитектуры, то есть ошибка, допущенная на этапе проектирования системы;
- несовершенность реального мира.
От первой причины избавиться очень сложно, от второй — невозможно.
Подпорки — это проявления несовершенной материи в программировании (которое «в принципе» не зависит от материального субстрата). Материя — это, в первую очередь, языки программирования, которые не могут быть универсальными. Но ничего другого, кроме этой несовершенной материи, у программистов нет.
Подпорки имеют свойство содержать множество ошибок и порождать новые подпорки. Профессиональный программист всегда старается свести число подпорок к минимуму (не впадая при этом в бесконечный цикл «design refining»), а если они все-таки есть, то тщательно их комментирует.
Призрак
правитьПризрак — значение либо условие, которое не отображено в строках кода программы, но необходимо для ее понимания. Это понятие дуально к понятию «подпорка».
Очень часто призраки — это предусловия (условия на входные данные), которые явно не следуют из предшествующих строк кода.
Другой пример призраков — математические теоремы, на которых основывается код и без которых сложно понять его логику и убедиться в его верности. (например, теоремы, на которых основано шифрование RSA).
Есть более прозаические примеры призраков: число шагов цикла while
,
либо инварианты циклов, либо требование упорядоченности массива, явно не следующее из кода.
Призраки — абстрактные сущности, на которых основан код, но которые в этот код не попали, а так и остались «в голове у программиста» (подпорки же обладают обратным свойством — они присутствуют в коде, но их назначение быстро забывается программистами).
Принцип самодокументированности кода (code self-documentation), провозглашенный в теории коллективной разработки программ, гласит: «Призраков быть не должно!»
Но что же делать? — Пишите комментарии и не забывайте про тесты!
Переиспользование — применение готовых программных модулей (уже использованных в другой программе либо кем-то другим) при создании нового программного обеспечения. Доля переиспользуемых программных решений выказывает качество организации работы программистской артели, но вовсе не обязательно — качество самой работы. Различные средства модульности и объектности создавались прежде всего с целью облегчить переиспользование. Но обычно они этой цели не достигали.
Вспоминая историю науки и техники, можно заметить, что переиспользование всегда было основным орудием математиков: у них все доказывается на основе ранее доказанного. В технике его удалось достичь, лишь отойдя от индивидуальной подгонки каждой детали и введя строжайшие стандарты и допуски на размеры и характеристики деталей; но это возможно лишь при выпуске одинаковых деталей.
Именно благодаря применению переиспользования удается создавать действительно сложные системы. Но излишнее стремление к переиспользование часто приводит к следующим негативным последствиям:
- программное обеспечение усложняется. Так, при проектировании учитывалось не столько назначение программного обеспечения и логика, сколько наличие нескольких готовых компонент, которые, как казалось, могли сократить трудоемкость разработки;
- универсальные кирпичики оказываются недостаточно универсальными, то есть не в достаточной степени решающие частные задачи: не совсем те задачи, или те, но не достаточно быстро, точно, без учёта особенностей конкретного случая.
Иными словами:
- Использовать иногда оказывается труднее, чем переписать заново.
- Переиспользование отвлекает проектировщика от концептуальной целостности и может повлечь ошибки в архитектуре.
Серьёзное программирование — это всегда не массовое производство, а производство уникальных изделий.
Чем больше программирование будет ориентироваться на материальное массовое производство, забывая об этой специфике, и чем дольше оно будет игнорировать опыт математики как чистую теорию (забывая о том, что математика точно так же, как программирование, занимается построением идеальных понятий, рождаемых конкретизацией наших идей силой нашей мысли под контролем нашей логики), тем дольше переиспользование будет оставаться коварной ловушкой, в которую попадались слишком многие.
Смотри также модульность, абстракция, принцип неповторения (англ. Don’t repeat yourself).
Термин «ортогональность» заимствован из геометрии. Две линии являются ортогональными, если они пересекаются под прямым углом, например, оси координат на графике. В терминах векторной алгебры две такие линии перемещения являются независимыми. Если двигаться параллельно оси X вдоль одной из линий, то проекция движущейся точки на другую линию не меняется.
Этот термин был введён в информатике для обозначения некой разновидности независимости или несвязанности. В грамотно спроектированной системе программа базы данных будет ортогональной к интерфейсу пользователя: вы можете менять интерфейс пользователя без воздействия на базу данных и менять местами базы данных, не меняя интерфейса.
Проектирование
правитьПроектирование — это поиск ответа на вопрос, как должна быть реализована система.
Это второй этап процесса разработки программного обеспечения (первый — генерация концептуальной идеи).
Главные задачи проектирования — подбор подходящего стиля и инструментария, а затем разбиение задачи на подзадачи, естественно представимые в виде реализуемых модулей или процедур и фиксация системы взаимосвязей между выделенными блоками.
Область знаний «Системный анализ» претендует на описание базовых принципов, позволяющих избежать ошибок во время проектирования:
- концептуальная целостность;
- модульность и переиспользование, использование иерархичных структур;
- универсальность (гибкость и расширяемость);
- простота, уменьшение числа связей;
- прагматичность;
- ..
Множество предлагаемых в различных учебниках принципов является достаточно эклектичным набором противоречивых идей. Основной же принцип всякого проектирования это:
- достижения баланса между дуальными концепциями,
как то, «универсальность и расширяемость — простота и достижение конкретной функциональности», «концептуальная целостность — полнота и удобство функциональности», «многофункциональность — внутренняя простота и поддерживаемость».
Для успешного проектирования необходимо просто знать о существовании этого дуализма, иметь представление о большом количестве различных принципов, знать негативные и позитивные стороны каждого принципа, видеть какая пара дуальных принципов является наиболее критической для поставленной задачи и наиболее аккуратно проконтролировать баланс этой пары.
Самым ценным (но наиболее трудным) способом проектирования является известный в теории творческого мышления принцип: выделить критическое проблемное противоречие (это как раз предыдущий пункт) и снять его, перейдя к более высоким уровням. Компромисс всегда паллиатив, но он достижим гораздо легче.
Это не так много, но и не так мало. Проектировщик должен владеть системным подходом к решению задачи, способностью выделять существенное, не отвлекаться на детали, не увлекаться оттачиванием мелочей, умением добиваться концептуальной целостности не забывая о реальной цели. Лучшим рецептом обучения проектированию является комбинация изучение оснований логики и участие в реальных проектах.
См. также
- О проектировании в контексте ортогональности.
В Википедии
Тестирование
править
Восходящее программирование
правитьХарактерная особенность Лиспа как вольно саморасширяемого языка: см. Лисп#Восходящее программирование.
Прототипирование
правитьПрототипирование — это быстрая «черновая» реализация базовой функциональности для анализа работы системы в целом. Для прототипирования используют языки высокого уровня абстракции (Java, Python, Haskell, …). После этапа прототипирования обязательно следуют этапы пересмотрения архитектуры системы, разработки, реализации и тестирования конечного продукта. На этапе разработки подготавливают систему тестов, по работе которых буду судить о качестве продукта. При реализации решения обычно используют другой, «более машинноориентированный» язык программирования (Си, Си++, …), пишут более аккуратный документированный код, а на тестирование системы тратят сравнительно большое количество усилий для достижения качественного результата. На этапе прототипирования выявляются важные архитектурные ошибки, вносятся поправки в интерфейсы модулей (перераспределяется функциональность между кусочками системы). Прототипирование по мнению многих программистов является самым приятным этапом разработки, так как малыми усилиями создается нечто более-менее работающее. Кроме того, во время прототипирования на программистов обычно «снисходит понимание» и они начинают «видеть», как система должна быть устроена.
Несвязность и закон Деметры
править
«Волшебники», частично автоматизирующие разработку систем
править
Надёжность
правитьБезусловно, программные средства (далее, тут и ранее — ПС) должны работать правильно и надёжно. Но оба упомянутых термина допускают большую свободу интерпретации. Например:
Работать правильно — это
- так, как представляет себе это заказчик;
- так, как понял и сформулировал менеджер проекта;
- так, как записал в тех. задании постановщик задания;
- так, как понял это задание программист;
- так, как решил сделать программист, который (иногда заслуженно) считает себя умнее постановщика задания, менеджера и, тем более, заказчика.
Ясно, что данные пункты могут отличаться, а полученное в результате ПС может отличаться от всех этих пунктов. Это отдельная тема, и мы не будем её здесь развивать. Предположим, что понятие правильности удивительным образом вполне чётко, полно и непротиворечиво описано в некоторой спецификации логики работы ПС.
Под надёжностью ПС можно понимать правильность работы для всех входных данных. Для большинства сложных систем такая абсолютная надёжность — очень серьезное требование. Часто оно просто недостижимо. Какой бы полной не была спецификация логики работы ПС, она просто не может включить (описать), каким должно быть поведение ПС в экстремальных условиях.
Например, к серверу может прийти слишком много запросов в секунду, может возникнуть ошибка на жестком диске, ошибка может случится в каких-то внешних к ПС подсистемах.
Понятие надёжность более адекватно (прагматично) отражает то, что в реальности можно требовать от ПС:
Надёжность ПС — это высокая вероятность правильности работы ПС как при нормальных так и при экстремальных условиях. Надёжность достигается за счет учёта возможных сбоев в различных подсистемах, от которых зависит работа ПС, и многоуровневой защиты от сбоев как внутренних, так и внешних подсистем.
В экстремальных ситуациях словосочетание «правильность работы» имеет смысл заменить на «логичность поведения ПС». Даже в экстремальных ситуациях ПС должно делать попытки «выжить» и обеспечить сохранность данных, а также предоставить возможность восстановления работоспособности после «перезагрузки».
Надёжность в значительной степени определяется отсутствием ошибок в коде. Но это не единственная составляющая надёжности. Надёжность обеспечивается архитектурой и внутренней логикой работы компонент.
Самодокументированность и самопроверяемость являются важными общепринятыми методологиями достижения надёжности кода. Они позволяют без тестирования продукта, малыми усилиями, обеспечить недопущение и устранение большого числа ошибок.
Кроме того, надёжность ПС гарантируется с помощью массового и многопланового тестирования ПС.
Также существуют специализированные инструменты, осуществляющие анализ кода и проверяющие выполнение необходимых условий. Эти условия указываются непосредственно в коде, и непосредственно связаны с требованиями, предъявляемыми к ПС в спецификации логики работы. Например, это могут быть post- и prerequisites conditions — условие, которым должны удовлетворять данные в момент вызова некоторой функции, и в момент завершения выполнения функции. Задача доказательства правильности работы программ довольно сложна, но уже есть прецеденты создания программ, для которых с использованием специальным программ доказано, что они всегда работают правильно.
Выделенное слово «всегда» и есть такое слово, степень приближения к которому измеряется надёжностью.
Неправильно думать, что надёжность достигается на этапах кодирования и тестирования. Думать о надёжности ПС следует начинать на этапе проектирования. В частности, уменьшение числа зависимостей между компонентами за счёт тщательно продуманной архитектуры и исключения лишних зависимостей позволяет уменьшить количество источников проблем, и тем самым облегчить задачу достижения надёжности на этапах кодирования и тестирования.
Часто излишнее стремление к надёжности приводит к слишком жесткой архитектуре и слишком медленному коду. Например, в коде в самых различных местах можно вставлять кусочки, проверяющие корректность данных и состояний устройств, с которыми будет связано следующее действие. Здесь, как и везде в информационных технологиях, важно чувствовать баланс и не доводить стремление к надёжности до паранойи. Важно распределить задачу достижения надёжности по различным этапам разработки ПС, на каждом этапе делать то, что может быть сделано на этом этапе меньшими усилиями, чем на других. Шаги, предпринимаемые для достижения надёжности, не должны сильно усложнять разработку.
Демон
правитьДемон — программная единица, которая активизируется не путем прямого вызова, а при наступлении некоторого события в системе. Демон отличается от обработчика события тем, что он программируется как автономная по отношению к вызывающим событие модулям единица, и часто даже формально принадлежит другой программной системе. Поэтому демон ничего не знает о событии, кроме факта, что оно произошло, и должен разобраться в ситуации, пользуясь доступной ему информацией. Примерами демонов служат некоторые обслуживающие программы (например, проверка и упорядочение файловой системы, файрволлы).