Архитектура программных систем

Архитектура программных систем

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

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

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

В современном мире умение считать и писать совершенно необходимо в процессе общения между людьми.

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

Давайте попробуем ответить на вопрос, что же представляют собой современные программные системы, определяющие интеллект компьютера?

Сложность программных систем

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

Есть весомые обоснования правильности такого ответа. Приведу некоторые из них:

  1. Размер. Современные программные системы могут иметь десятки миллионов строк кода.
  2. Коллектив разработчиков. Программная система может создаваться коллективом, включающим сотни разработчиков.
  3. Время жизни. Программная система может жить не один десяток лет, подвергаясь непрерывным изменениям.
  4. Интеллектуальная сложность системы. В программных системах реализуется интеллектуальная мощь знаний, накопленных человеком в самых разных областях его деятельности.
  5. Техническая сложность компьютеров. Ни одно из технических средств, созданных человеком, не развивается столь стремительно как компьютеры.

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

Такие системы получили название операционных систем (ОС), сегодня ни один из компьютеров не выпускается без встроенной операционной системы, являющейся теперь неотъемлемой частью компьютера. Существенный прорыв в создании ОС был сделан в конце 50-х, начале 60-х годов прошлого столетия, когда в фирме IBM была создана ОС-360. Для ее создания потребовалось 5000 человеко-лет (1000 сотрудников фирмы в течение 5-и лет создавали первую версию системы). По затратам труда, по значимости этого проекта американцы сравнивали его с лунным проектом  — проектом достижения человеком луны.

По нынешним меркам ОС – это достаточно простая программная система, нынешние системы намного сложнее, масштабнее, чем ОС-360.

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

Сложность разработки программной системы может быть связана не только со сложностью самой задачи, но и со сложностью самого компьютера, ресурсы которого требуется эффективно использовать. Наиболее мощные на данный момент компьютеры принято называть суперкомпьютерами. Понятие это относительное, поскольку через 10 -15 лет компьютеры с параметрами нынешних суперкомпьютеров относятся к категории обычных, рядовых компьютеров. На момент написания этих строк первым в списке Топ-500 наиболее мощных суперкомпьютеров идет суперкомпьютер Китая – Тьянхе 2. Этот компьютер имеет сложную архитектуру, состоит из 16 000 вычислительных узлов, представляющих многоядерные процессоры разных типов. В совокупности число ядер этого компьютера составляет более 3-х миллионов, а его быстродействие исчисляется числом с 16-ю нулями. Создать программную систему для такого компьютера, которая позволяла использовать все его возможности – сложнейшая задача. В такой программной системе нужно уметь распараллелить процесс вычислений, чтобы в вычислениях одновременно были заняты все ядра компьютера. Нужно уметь синхронизировать параллельно исполняемые вычислительные процессы, обеспечить их взаимодействие, обмен информацией. Непростые задачи стоят перед программистами, создающими программы для суперкомпьютеров.

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

Как бороться со сложностью программных систем

Два взаимосвязанных приема позволяют справиться со сложностью программных систем:

  1. Модульное построение системы;
  2. Повторное использование кода.

Модульное построение системы

Возможности человека ограничены. Безнадежная задача пытаться построить программную систему, как нечто цельное, как единый модуль. Единственно возможный способ справиться с решением поставленной задачи состоит в том, чтобы разбить нашу задачу на N подзадач, совместное решение которых дает решение исходной задачи. При этом можно надеяться, что подзадачи менее сложны, чем исходная задача. Число N обычно невелико и удовлетворяет условию «Семь плюс минус Два». Считается, что человек способен анализировать связи между элементами системы, когда число элементов системы не превышает 10. Уже при пяти взаимосвязанных элементах система считается сложной.

У Айзека Азимова в его знаменитой серии рассказов о роботах, есть рассказ о роботе, управляющем работой 10 роботов, занимающихся горными разработками на далекой планете. Время от времени роботы прекращали работу и начинали бессмысленное кружение. Пара друзей, занимающихся испытанием и наладкой роботов, пытались найти причину возникающих неисправностей. Во время наблюдения произошел непредвиденный взрыв в шахте, и наблюдателей завалило, осталось лишь небольшое отверстие, в которое они могли наблюдать за танцем потерявших разум роботов. Как Вы думаете, какой выход нашли испытатели в этой критической ситуации? Один из них догадался, в чем причина «потери разума» у управляющего робота. Число управляемых роботов достаточно велико, в критических ситуациях таких, как взрыв в шахте, необходимо было одновременно управлять всеми исполнителями, число связей возрастало и робот «терял разум». Донован – один из испытателей, отстрелил несколько роботов – исполнителей, к управляющему роботу возвратился разум, все закончилось благополучно.

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

Идея модульного построения системы проста и понятна. Сложность в ее реализации состоит в том, что разделение системы на подзадачи – это не формализуемый, творческий процесс. Ничто не гарантирует, что на каком-то этапе, вы не получите подзадачу, для которой не сможете найти решение.

Процесс разбиения системы на подсистемы называется процессом построения архитектуры системы. Это самый ответственный этап. Программисты, разрабатывающие архитектуру системы, называются архитекторами. От успеха их работы зависит, как правило, успех всей разработки.

Повторное использование кода

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

Реально ситуация не такая. Процесс проектирования системы не начинается на пустом месте. К началу разработки новой системы имеется большое число уже готовых модулей, созданных при разработке других систем. Проектирование архитектуры системы может идти «снизу – вверх», когда система собирается из уже готовых модулей, аналогично тому, как из деталей конструктора «Лего» можно собрать новую машину. На практике в процессе проектирования системы участвуют оба подхода «сверху – вниз» и «снизу – вверх». Проектируя «снизу», мы пытаемся из готовых модулей собрать подзадачи. Проектируя «сверху» мы пытаемся свести исходную задачу к уже известным подзадачам.

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

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

  • «Нули и единицы». Программные системы – это системы не материального мира. Для их построения не нужна нефть, не нужен газ, не используется сталь и дерево, никакие другие материалы. Они создаются силой разума из нулей и единичек. В процессе работы системы создается виртуальный мир, возможно моделирующий реальный мир. Мир, где создаются объекты, они взаимодействуют друг с другом, исчезают и появляются снова. Программная система задает описание этого мира. Компьютер позволяет оживить этот мир.
  • «Copy – Paste». Нет ничего проще создания копии системы. Однажды созданный модуль может тиражироваться многократно, существовать во множестве экземпляров и быть строительным блоком во многих проектах. Модуль не стареет, не изнашивается в процессе эксплуатации. Повторное использование кода практически не требует никаких затрат.