Под программной системой я подразумеваю программную часть разрабатываемой человеко-машинной системы (информационной системы).
Именно проблема сложности, на мой взгляд, и есть главная причина "кризиса программирования". А точнее, не сама сложность (мир вообще сложен, не только программные системы), а практически полное ее игнорирование. Разработчики операционных систем, прикладных пакетов, средств разработки, не моргнув глазом делают мир программного обеспечения все сложнее и сложнее, причем большая часть привносимой ими сложности ничем не оправдана. Все это можно было сделать ничуть не хуже (а то и лучше), но проще. Недавно я нашел в Интернете такой лозунг "Small is Beautiful" (простое прекрасно), вы думаете это имело отношение к какому-нибудь популярному продукту типа Microsoft Office? Нет, это был документ "Философия Unix" (http://hebb.cis.uoguelph.ca/~dave/27320/new/unixphil.html). По-моему, только там (unix, GNU, OSF - фонд бесплатных программ) это еще кого-то интересует.
Это все напрямую касается темы нашего разговора, потому что разработчикам системы придется пользоваться всем этим (плохими компиляторами, БД и т.п.). Кроме того, разработчики системы сами могут совершить аналогичную ошибку и усложнить себе жизнь.
Из всего сказанного, я думаю, уже ясно, что очень важно уменьшить сложность разрабатываемой системы.
Искусственная сложность наоборот, в основном на совести тех, кто проектирует и программирует систему.
Для определенности введем еще один термин.
Неоправданная сложность - это сложность не обоснованная ни какими реальными потребностями заказчика. В нее целиком входит искусственная сложность и часть объективной.
Неоправданная сложность, к сожалению, всегда больше, чем искусственная. Это означает, что почти всегда часть объективной сложности составляет сложность достижения тех целей, которые на самом деле не нужны. Но в тот момент, когда они ставились, мы этого не понимали и поэтому включили их в цели проекта. Конечно, важно выявлять такие цели и исключать их из проекта, сводя тем самым неоправданную сложность к искусственной. Но, как я уже говорил, проблема уменьшения объективной сложности выходит за рамки этой статьи.
Итак, мы сосредоточимся на уменьшении искусственной сложности, а точнее, той ее части, на которую мы можем повлиять.
Искусственную сложность можно также разделить на две категории:
Теперь, наконец, о самом интересном - о тех проблемах, которые мы (разработчики) сами себе создаем, о собственной искусственной сложности. Ее можно уменьшать разными способами и, многие хорошие разработчики их применяют, возможно, даже не осознано, на интуитивном уровне. Я называю это естественным подходом.
Поэтому, на мой взгляд, можно резко повысить надежность программ, уменьшив искусственную сложность. А если можно, и объективную.
Конечно, есть и другие подходы к увеличению надежности и, многие из них очень эффективны. Но мы говорим о сложности и, в данном случае мы получим повышение надежности просто как следствие уменьшения неоправданной сложности программы.
Это придумали давно и, в более известном варианте это звучит так: "некрасивая машина не работает". К сожалению, этот принцип не часто соблюдается, а в программировании в последнее время вообще почти игнорируется.
Конечно, вы можете сказать, все это прекрасно, только не известно, что такое естественно и что такое красиво. Известно, по крайней мере, в достаточной степени, чтобы этим можно было пользоваться. Если разработчик программной системы следует естественному подходу, осознано или не осознано, то через некоторое время у него образуется соответствующая шкала ценностей и он начинает отличать плохое от хорошего.
Например, Sql задумывался с целью уменьшить сложность работы с БД (вплоть до того, чтобы это могли делать простые пользователи). В результате, эти прогнозы в какой-то степени оправдались только на игрушечных примерах из нескольких простых таблиц, а во всех остальных (реальных и нужных) случаях сложность напротив возросла. Сейчас разработчики использующие Sql имеют много проблем, вызванных исключительно им самим. Например, оптимизация запросов или отображение реальной задачи в искусственную среду из кучи таблиц.
Или взять, например, средства разработки типа VisualBasic. С точки зрения профессионального программиста они имеют огромную искусственную сложность. Взамен предлагая сомнительное (для профессионала) преимущество более быстрого освоения. Сомнительное, потому что лучше один раз потратить время на преодоление сложности освоения (кстати, ее можно квалифицировать как объективную), чем постоянно тратить время на преодоление искусственной сложности плохого продукта.
Код программы тоже можно рассматривать как модель проекта программной системы. Таким образом, весь цикл разработки программной системы можно представить в виде серии отображений из одной модели в другую, начиная с высокоуровневых абстракций в терминах прикладной области и кончая кодированием на самом низком уровне.
Теперь, посмотрев на разработку программной системы с этой точки зрения, можно заметить, что для построения хорошей программной системы необходимо свести к минимуму искажения при отображении из одной модели в другую. Иначе вместо разработки системы мы получим игру в испорченный телефон. Как этого достичь?
В процессе отображения из одной модели в другую происходит трансформация понятий исходной в понятия результирующей модели. Например, понятие "пользователь системы" может трансформироваться в объект типа User в программе, написанной на C++, а может - в строчку реляционной таблицы. Иерархия прав пользователя может трансформироваться в иерархию объектов типа UserPermission, а может, опять же, в реляционные таблицы. Но реляционные БД не позволяют легко естественно моделировать иерархию. Попробуйте, например, сравнить реализацию двоичного дерева средствами обычного языка и средствами SQL. Да, напишите обход этого дерева. После такой попытки, я думаю, вам станет ясно, что отображение иерархии в реляционные таблицы искажает исходные понятия и, в результате, мы получаем испорченный телефон. Происходит отрыв программы (модели нижнего уровня) от проекта и задачи (моделей более высокого уровня). Это неизбежно ведет к росту сложности и разработки, и сопровождения. Что и требовалось доказать.
Итак, средства, вызывающие искажения при отображении из одной модели в другую, вносят в программную систему искусственную сложность, следовательно, не являются естественными.
Система будет тем лучше, чем ближе модель к тому, что она моделирует. Это означает, что модель должна оперировать с понятиями, близкими к задаче (предметной области).
Естественные средства позволяют строить модели более адекватные и естественные.
Под это непросто подвести математическую теорию (в отличие, скажем, от реляционной технологии), эта технология сложна как и сам мир. Но она позволяет его естественно моделировать. Она позволяет рассматривать очень сложные системы как системы, состоящие из взаимосвязанных объектов, позволяет при необходимости абстрагироваться от их внутреннего устройства (инкапсуляция). Все участвующие в разработке (аналитики, программисты, проектировщики) получают возможность работать в терминах объектов. Исчезает разрыв между проектированием в терминах предметной области и, скажем, проектирования БД в терминах реляционных таблиц (объектно-ориентированную БД также можно проектировать в терминах объектов).
Понятия предметной области теперь могут использоваться в течении всего цикла разработки системы (вплоть до кодирования). На стадии анализа эти понятия выявляются и описываются на неформальном языке. Далее, на этапе проектирования эти понятия постепенно формализуются, трансформируются в заготовки объектов. На этапе программирования они превращаются в полноценные объекты. Разработка естественно, происходит не последовательно, а циклически. Периодически повторяются и анализ, и проектирование, и программирование, и не обязательно строгого в этом порядке.
Все это позволяет снизить сложность разработки (точнее искусственную сложность).
Чтобы реально использовать OO технологию, недостаточно просто использовать средства, которые рекламируются как объектно-ориентированные. Надо прочувствовать смысл этой технологии, научиться ее применять на практике.
Объектно-ориентированное программирование (OOP) далеко не вся ОО технология, анализ и проектирование системы тоже должны быть объектно-ориентированными (OOA и OOD). В общем, необходимо перестроить все свое мышление, изменить всю философию разработки программных систем.
Очень не просто найти компромисс между чистой ОО технологией и реальными задачами, требованиями (например, по части скорости выполнения программ).
На это вполне может уйти несколько лет.
Одна из проблем, затрудняющих понимание ОО технологии, связана с тем, что эта технология предназначена для применения ее в при разработке сложных систем и, поэтому ее трудно проиллюстрировать на простых примерах.
Далеко не все из средств разработки, рекламируемые как объектно-ориентированные, реально поддерживают эту технологию. Многие просто вещают ярлык "ОО технология" как дань моде и для привлечения покупателей.
То же самое относиться и к книгам. Если вы хотите почитать про объектно-ориентированное программирование, проектирование и анализ, то вы можете доверять книгам Б.Стауструп-а (автора языка C++) и Г.Бутч-а (книга по OO технологии).
Хоть это все не просто, но эти технологии можно освоить и, тогда они помогут справиться со все возрастающей сложностью в мире программирования. Я занимаюсь этим где-то около 8 лет и, оглядываясь в прошлое, думаю, что не ошибся, это дает результаты.
C++
C++ являет собой компромисс между чистой ОО технологией и традиционными подходами (включая совместимость с языком "C") . Он также позволяет создавать быстро работающие программы (в этом он, практически, не хуже обычного "C"). Из всех перечисленных языков C++ обладает самой мощной поддержкой ОО технологии.
Кроме того, C++ поддерживает и другие, не объектно-ориентированные технологии программирования.
С++ универсальный язык, на нем можно написать и операционную систему, и информационную систему предприятия. С++ поддерживается международными стандартами и не зависит от какой-то одной фирмы.
Smalltalk
Smalltalk проповедует чистую ОО технологию и поддерживает только ОО технологию. Он также является интерпретатором и, программы, написанные на нем, работают не слишком быстро (что, вообще говоря, делает его не совсем универсальным). Smalltalk также как и C++ поддерживается международными стандартами и не зависит от какой-то одной фирмы.
TurboPascal
Начиная с 5-ой версии, TurboPascal стал объектно-ориентированным. Этот язык вполне поддерживает ОО технологию. Он постоянно перенимает у C++ все новое (естественно, с запозданием). В этом смысле он вторичен по отношению к C++. TurboPascal создала фирма Borland и он целиком от нее зависит. Насколько мне известно, никакими стандартами (ANSI, ISO) не поддерживается. Не известно, что с ним будет, если, например, фирма Borland обанкротится.
URL: http://geocities.datacellar.net/SiliconValley/Horizon/3810/tech-win.html