Рис. 1. Схема процесса создания программной
модели (класса) в рамках ООП.
Следующим шагом в исследовании задачи будет построение информационной модели объекта. Здесь требуется дать названия свойствам, установить диапазоны возможных значений свойств и определить их типы. Выяснить, что считать исходными данными и что считать результатами. Определить возможные места расположения данных. Если эти данные расположены или в результате решения будут располагаться на внешних носителях, например в виде файлов, нужно описать структуру, в которой они представлены или будут представляться на этом носителе.
Построение математической модели сводится к записи математических соотношений, связывающих результаты или новые свойства с исходными данными. Эти соотношения, как правило, представлены в аналитическом виде формулами.
Информационная и математическая модели служат основой для построения программной модели объекта или класса.
Построение класса начинается с разработки его интерфейса. Поля класса формируются из информационной модели. А в методы класса, помимо стандартных методов (конструкторов и деструктора), включаются методы, связанные с изменением свойств объекта, получением новых свойств как воздействием на объект, так и на основании соотношений, заявленных в математической модели.
Та последовательность действий, которая представлена на рис. 1, исходит из того, что в задаче уже выделены физические объекты. Именно физические объекты определяют интерфейс программы в целом, ее программную модель и в значительной степени влияют на логику решения задачи.
Выделение объектов само по себе не является простой задачей. Для выделения объектов в части анализа и исследования задачи значительное место отводится разработке концептуальной модели функционирования пользовательского интерфейса.
Важность этапа разработки концептуальной модели пользовательского интерфейса сложно переоценить также из-за возросших требований к качеству программного продукта как на отечественных, так и на западных рынках, т. к. в оценку программного продукта входит качество интерфейса, обеспечивающего взаимодействие пользователя с программой.
В. Головач [2] отмечает четыре основных критерия качества интерфейса, а именно:
1) скорость работы пользователей;
2) количество человеческих ошибок;
3) скорость обучения;
4) субъективное удовлетворение (подразумевается, что соответствие интерфейса задачам пользователя является неотъемлемым свойством интерфейса).
Скорость выполнения работы является важным критерием эффективности интерфейса. Длительность выполнения работы пользователем состоит из:
¾ длительности восприятия исходной информации;
¾ длительности интеллектуальной работы (пользователь думает, что он должен сделать);
¾ длительности физических действий пользователя;
¾ длительности реакции системы.
Как правило, длительность реакции системы является наименее значимым фактором. Процесс разработки дизайнов интерфейсов в настоящее время является настолько важным составляющим элементом при создании программного продукта, что он стал профессией отдельных людей. Появились научные разработки в области проектирования пользовательского интерфейса, которые опираются на познавательные процессы человеческого сознания, т.е. знания из областей когнитивной и инженерной психологии, а также эргономики.
Согласно Дональду Норману, на которого ссылается В. Головач, взаимодействие пользователя с системой (не только компьютерной) состоит из семи шагов:
1) формирование цели действий;
2) определение общей направленности действий;
3) определение конкретных действий;
4) выполнение действий;
5) восприятие нового состояния системы;
6) интерпретация состояния системы;
7) оценка результата.
Из этого списка становится видно, что процесс размышления занимает почти все время, в течение которого пользователь работает с компьютером, во всяком случае шесть из семи этапов полностью заняты умственной деятельностью. Соответственно, повышение скорости этих размышлений приводит к существенному улучшению скорости работы.
К сожалению, существенно повысить скорость
собственно мышления пользователей невозможно. Тем не менее, уменьшить влияние
факторов, замедляющих процесс мышления, вполне возможно. Очевидно, что значение
этапа проектирования интерфейса приложения трудно переоценить. На нем
закладываются основные концепции системы, ее структуры, а также выделяются
объекты для проектирования классов.
3. Исследование эволюции
объектно-ориентированных языков программирования
Первым объектно-ориентированным языком был Simula-67. Его идеи и концепции легли в основу последующих объектно-ориентированных языков программирования. То есть язык Simula-67 является тем «паттерном», с которого начинается ТРИЗ-эволюция ООП. Язык Simula-67 был построен на основе языка Algol-60 [4]. Особенностью Simula-67 является наличие у объекта параметров. Simula-объект - это программная компонента, характеризующаяся некоторыми атрибутами (данными и процедурами) и способная выполнять определенные действия, описываемые ее правилами действий.
Язык можно охарактеризовать набором механизмов реализации объектно-ориентированных возможностей (рис. 2). Simula-67 выступает «первенцем» ООП, и набор механизмов в языке нельзя назвать идеальным. С увеличением сложности решаемых объектно-ориентированных задач разработчики столкнулись с рядом противоречий.
В языке для выполнения однотипных операций с различными типами данных используются разные функции, т.е. с увеличением количества типов данных недопустимо увеличивается количество функций, обозначающих одно и то же действие (противоречие 1).
Рис. 2. Фрейм языка Simula-67 и положение языка
Simula-67 на S-образной кривой
Также существенными недостатками языка являются отсутствие средств для отладки приложения и необходимость выполнения определенного алгоритма действий для запуска программы. При отладке крупных приложений на выполнение этого алгоритма и поиск причины ошибки, не выявленной компилятором, тратится много времени, т.е. с увеличением сложности разрабатываемого ПО недопустимо увеличивается время на отладку программы (противоречие 2). Также такие ошибки приводят к аварийному завершению программы. И чем больше объем кода, тем больше вероятность пропустить подобную ошибку, т.е. с увеличением объема кода недопустимо снижается надежность программы (противоречие 3).
Кроме того, при реализации механизма одиночного наследования в языке возникает противоречие: с увеличением количества возможных классов-родителей недопустимо увеличивается объем дублируемых данных (противоречие 4).
Перечисленные выше и другие противоречия были разрешены в языках Smalltalk-80, С++, Eiffel.
Основная особенность языка Smalltalk (рис. 3) в
том, что все переменные являются объектами, взаимодействие между которыми
происходит через обмен сообщениями. Классы хранятся в дереве классов и связаны
отношением наследования. При этом любой класс является объектом класса более
высокого порядка. Написание программы на языке Smalltalk заключается в
последовательном изменении состояния ее объектов [13]. Использование механизма
компиляции в промежуточное представление позволяют запускать программу на
аппаратных платформах, где поддерживается виртуальная машина Smalltalk.
Рис. 3. Фрейм языка Smalltalk и положение языка
Smalltalk на S-образной кривой
Часть противоречий Simula-67 была разрешена в языке Smalltalk-80 следующими инструментами ТРИЗ. Например, при использовании приема «универсальности» в язык была добавлена возможность перегрузки операторов, т.е. возможность одновременного существования в одной области видимости нескольких различных вариантов применения оператора, имеющих одно и то же имя, но различающихся типами параметров, к которым они применяются (решение 1.1). С помощью закона перехода в надсистему создана среда разработки программы, обладающая пользовательским интерфейсом и предоставляющая средства для отладки программ (решение 2.1).
Таким образом, в языке появилось большое
количество новых механизмов реализации ООП. Произошла первая итерация
ТРИЗ-эволюции (рис. 4).
Рис. 4. Первая итерация ТРИЗ-эволюции механизмов
ООП
Несмотря на то, что в языке Smalltalk-80 была разрешена часть противоречий Simula-67, Smalltalk-80 унаследовал ряд противоречий этого языка.
Далее рассмотрим язык С++ (рис. 5), это один из
популярных объектно-ориентированных языков программирования, созданный в 1983
году Б. Страуструпом [7]. Результатами создания экземпляров в языке являются
просто объекты, или объявления данных. Классы могут называть один или несколько
родительских классов, обеспечивая наследование и множественное наследование
соответственно [6]. В С++ введена возможность описания параметризированных
классов и функций (шаблонов), а также возможность описания обработки
исключительных ситуаций в программе.
Рис. 5. Фрейм языка С++ и положение языка С++ на
S-образной кривой
В языке С++ при использовании приема «самообслуживание» к языку была добавлена возможность обработки исключительных ситуаций. Данный механизм предназначен для описания реакции программы на ошибки во время выполнения (решение 2.2).
При использовании приема «универсальность» совместно с приемом «наоборот» к языку была добавлена возможность описания шаблонов, при инициализации которых аргументами выступают типы значений, а не сами значения. В целом шаблоны - средство языка, предназначенное для кодирования обобщённых алгоритмов без привязки к некоторым параметрам (решение 3.1)
При использовании приема «объединение» были введены возможность объединения дублируемых параметров в одном из классов и возможность объекту наследовать несколько классов, т.е. появился механизм множественного наследования (решение 4.1).
Таким образом, произошла вторая итерация ТРИЗ-эволюции (рис. 6).
Для языка С++ также существует ряд противоречий.
Например, использование технологии множественного наследования порождает
проблемы, связанные с неоднозначностью выбора из одноименных методов
родительских классов. Например, если вызвать метод для объекта Show() и в
классе его не окажется, но в классах-родителях будет присутствовать метод
Show(), определенный по-своему, то какой из методов должен быть вызван? Таким
образом, с увеличением количества классов-предков при множественном наследовании
недопустимо увеличивается неоднозначность выбора одноименных методов
(противоречие 5).
Рис. 6. Вторая итерация ТРИЗ-эволюции механизмов
ООП
Далее рассмотрим язык Eiffel (рис. 7). Eiffel не мультипарадигменный язык, он не позволяет сочетать в одной программе несколько стилей. В Eiffel есть несколько важных черт, поддерживающих жесткий стиль программирования, таких как параметризованные классы, утверждения и исключения.
В языке Eiffel были разрешены не только часть противоречий C++, но и противоречия предыдущих языков.
Так, при помощи приема «предварительное действие» были разработаны дополнительные операторы, регулирующие порядок наследования и вызова функций (решение 5.1).
Рис. 7. Фрейм языка Eiffel и положение языка
Eiffel на S-образной кривой
Также в языке Eiffel при использовании приема «предварительное действие» разработан механизм «Проектирование по контракту», который позволяет задавать различные типы условий (контракты), проверяемых во время работы программы. При нарушении одного из пунктов контракта наступает заранее обговоренная и согласованная мера (решение 2.3).
Таким образом, произошла третья итерация
ТРИЗ-эволюции (рис. 8).
Рис. 8. Третья итерация ТРИЗ-эволюции механизмов ООП
Аналогично были проанализированы следующие популярные объектно-ориентированные языки: Python; Java; Delphi; Perl 6; C#; Scala; PHP; Objective C; Ruby.
Общая ТРИЗ-эволюционная карта механизмов ООП представлена на рис. 9.
Языки Delphi, C#, Scala, PHP, Objective C, Ruby
не отражены на ТРИЗ-эволюционной карте в связи с тем, что противоречия, которые
были разрешены в этих языках, не затрагивают объектно-ориентированный подход
либо совершенствуют реализацию уже существующих механизмов ООП.
Рис. 9. ТРИЗ-эволюционная карта механизмов ООП
Использование данной карты позволит существенно повысить эффективность обучения за счёт систематизации знаний, в данном случае - знаний о механизмах реализации объектно-ориентированных возможностей в различных языках программирования.
С учётом критерия оценки степени реализации
объектно-ориентированных возможностей была построена S-образная кривая (рис.
10), которая наглядно показывает, как изменялась степень реализации
объектно-ориентированных возможностей в различных языках программирования.
Серым выделены языки, не внёсшие вклад в развитие этих возможностей.
Рис. 10. S-образная кривая для объектно-ориентированных
языков программирования
Проведённый анализ объектно-ориентированных языков программирования позволил:
¾ систематизировать знания о существующих механизмах реализации объектноориентированных возможностей;
¾ обосновать эволюцию механизмов ООП;
¾ определить ТРИЗ-инструменты разрешения противоречий, которые стали движущей силой эволюции;
¾ построить ТРИЗ-эволюционную карту механизмов ООП, которая позволяет существенно интенсифицировать процесс обучения студентов ООП.
Заключение
В настоящее время насчитывается более двух тысяч языков программирования высокого уровня. Большинство этих языков возникло исходя из конкретных требований некоторой предметной области. Каждый новый язык позволял переходить ко все более и более сложным задачам. На каждом новом приложении разработчики языков что-то открывали для себя и изменяли свои представления о существенном и несущественном в языке. На развитие языков программирования значительное влияние оказали достижения теории вычислении, которые привели к формальному пониманию семантики операторов, модулей, абстрактных типов данных и процедур.
К настоящему времени насчитывается более сотни различных объектных и объектно-ориентированных языков.
Объектно-ориентированное программирование является в настоящее время основой всей индустрии прикладного программирования благодаря выигрышу в конкурентной борьбе с альтернативными технологиями.
Концепция ТРИЗ-эволюционности знаний позволяет наметить подходы к разрешению основного противоречия образования между объёмом передаваемых знаний и временем на их освоение. Существует фрактальный подход к исследованию объектов различной природы. Укрупнено развитие (эволюция) фрактального объекта происходит следующим образом. Исходный объект (паттерн) в соответствии с правилами эволюции (законами эволюции), используя ресурсы окружающей среды, многократно воспроизводится (копируется), увеличивая при этом свою «сложность».