Мегаобучалка Главная | О нас | Обратная связь


Современное состояние языков программирования.



2019-11-13 234 Обсуждений (0)
Современное состояние языков программирования. 0.00 из 5.00 0 оценок




С одной стороны, развивается подход разработки, ориентированной на моделях (MBSE, моделеориентированная системная инженерия). В качестве моделей используются объектные модели; диаграммы классов, пакетов, диаграммы взаимодействия в UML; модели требований; модели процесса разработки (методологии разработки); языки описания предметной области DSL; языково-ориентированное программирование ( language - oriented framework ).

 

 

С другой стороны, программирование на основе ООП становится всё более компонентно-ориентированным, собранных из готовых компонентов. И относительно редко возникает необходимость в доработке компонент.

 


С третьей, новые ООП языки демонстрируют новые подходы:

как подходы к реализации, например:

  • Язык Google Go – подход ad hoc интерфейсов. В языке Go не требуется описывать, что класс реализует такой-то интерфейс; наоборот, как только класс реализует определённый метод, он автоматически реализует интерфейс, в котором определён такой метод. То есть, теперь интерфейсы определяются по классам по ситуации, ad hoc . Это заметно упрощает программирование таких процессов, как например, сериализация, реализация криптографии, ввод-вывод.
  • Язык D (автор Волтер Брайт) – метапрограммирование на основе CTFE функций.
    • Метапрограммирование – это написание программы, которая пишет программы.
      • Как пример метапрограммы, можно привести программу вычисления синуса.
        Обычным алгоритмом синус вычисляется разложением в ряд, но тогда время вычисления алгоритма зависит от аргумента.  Если составить таблицу значений вида (x;sin(x)), то по такой таблице можно вычислить за один шаг. Составление такой таблицы – это и есть программа, которая пишет таблицу, по которой другая программа считает, то есть,  метапрограммы.

    • CTFE , или Compile - Time Function Execution – это выполнение функций программы во время компиляции. Например, печать отладочных сообщений. В языке D это выполняется гораздо проще, поскольку во время компиляции доступна любая описанная выше функция, с некоторыми ограничениями. Таким образом, метапрограмма значительно упрощается и по виду напоминает обычную программу.

Так и концептуальные подходы:

  • Функицонально-объектно ориентированное программирование, например: языки Scala, F#. Здесь язык одинаково просто поддерживает как функциональную, так и ООП парадигмы, но при этом и оба подхода более «интегрированы» в язык, чем в обычных мультипарадигменных языках. Так, в F# есть дальнейшее развитие идеи замыканий, active records (похожим образом устроен LINQ в C#).

 

Выводы по первой лекции.

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

ООП является одной из наиболее практичных парадигм программирования – развитием подхода структурного императивного программирования и абстрактных типов данных (ADT).

Развитие ООП проявляется в развитии теории ОО анализа и проектирования, в разработке на основе моделей. Практика ОО анализа и проектирования состоит в практическом освоении сложившихся шаблонов проектирования, объектных моделей, моделей архитектуры приложения, методологии разработки. Методологии ООП программирования развиваются в сторону увеличения гибкости методологий, ориентации на быструю разработку приложений (RAD), и полную поддержку жизненного цикла программных систем (ALM).

 

Лекция 2

Основные принципы реализации ООП

Первым ОО языком является язык Simula-67, придуманный Кристеном Нйигаардом в 1967 году. Язык применялся в университетах Дании для преподавания ООП программирования и для разработки концепций ООП. Применялась статическая типизациясистема типов языка позволяла наряду со стандартными базовыми типами (число вещественное, целое, строки) создавать пользовательские классы, в которых задавались свойства и методы (процедуры и функции).


Объекты – это переменные типа класс. Класс – это тип, задаваемый пользователем, который может иметь структуру (переменные-свойства) и поведение (методы).

Классы связаны между собой отношениями, или фундаментальными принципами реализации:

 

· Инкапсуляции – класс скрывает реализацию своих методов. Для вызова метода не нужно знать, как именно реализован метод, достаточно знать его поведение.

 

· Наследования – класс-потомокнаследует  у класса-предка, суперкласса свойства и методы. Это обеспечивает повторную используемость поведения предка потомком. Если перекрыть реализацию класса-предка в потомке, поведение можно переопределить.

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

 

Программирование в ООП парадигме состоит в составлении такого набора базовых классов, реализованных в библиотеках (программных каркасах, или frameworks ) и классов-наследников, которые в нужных местах перекрывают заданное в базовых классах поведение, и совместно решают задачу.

 

В процессе моделирования составляется иерархия классов, связанных отношением наследования (is-A) – например, класс-потомок и его предок, суперкласс. Кроме того, некоторые классы включают другие как составные части: это отношение аггрегации, композиции (has-A) –  например, класс «Массив» и класс «Элемент массива».

 

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

Поскольку иерархию классов можно составить произвольным образом, для эффективности необходимо соблюдать принципы объектно-ориентированного проектирования классов (см. следующие лекции).

 

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

При вызове метода класса, или метода объекта (переменной типа класс), производится поиск метода по типу класса (статическая диспетчеризация методов).

Например: пусть o – переменная класса О, то есть объект. Тогда
O.method1(a,b,c) – вызов метода method1 класса O с сигнатурой method1(a,b,c).

o.method2(d,e,f) – вызов метода method2 объекта o, то есть, переменной типа класса О.

 

При вызове метода происходит диспетчеризация:

· Метод method2(d,e,f) ищется по сигнатуре в описании класса.

· Вызывается метод, возвращается его результат (если этот метод – функция).

 

Поскольку все типы известны заранее до компиляции, такую таблицу можно составить с однозначным соответствием.

 

Возможен случай, когда метод не найдётся в классе О.

Если класс O имеет суперкласс Os , то есть, класс O наследует от класса Os, то метод ищется в классе Os. И так далее, если Os сам наследуется от другого класса, вплоть до базового класса Object, у которого нет суперкласса.

 

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

реализацию объектной модели этим языком.

 

Так, например: объектная модель языка Simula-67, практически без существенных изменений была приспособлена к необъектному языку C. В итоге Бьярн Страуструп придумал язык С++. В дальнейшем, эта же объектная модель была применена при разработке языков Java, C#, D, в немного изменённом виде – в Delphi.

 

С другой стороны, объектная модель языка SmallTalk была применена в языке Objective C. Брэд Кокс, автор Objective C проводил аналогию объектов с software circuits vs. integrated circuits.

 

Язык SmallTalk можно назвать «чистым» объектно-ориентированным языком: то есть, любая переменная в этом языке – это объект. В том числе, строка – это объект класса строка, число – объект класса число,  оператор – это объект класса блок, объект – это объект класса класс, а сам класс – это объект другого класса метакласс.  В языке SmallTalk, чтобы породить новый объект, не используется специальная конструкция или функция; вместо этого вызывается метод new : нужного класса «метакласс».

 

Для диспетчеризации, то есть, поиска методов по классам, в SmallTalk используется «посылка сообщений». То есть, объект – это закрытая (инкапсулированная) сущность, которая умеет «отзываться» на определённые (при задании класса) запросы, например, поиск метода по сигнатуре.

Для этого в классе метакласс ищется метод, и если он не найден – объекту посылается сообщение (вызывается метод) doesNotUnderstand: . Если объект реализует этот метод, он может перехватить процесс диспетчеризации и искать дальше, руководствуясь собственной логикой.

 

Таким образом, в SmallTalk происходит динамическая диспетчеризация методов:

тип (сигнатура) метода неизвестна заранее (во время компиляции программы), и окончательно становится известной только на момент запуска программы (потому что логика перекрытия методов определяется самой программой).

 

Иными словами, объектная модель задаёт способ диспетчеризации методов:  статический или динамический.

Далее, диспетчеризация методов может быть однозначной и одиночной (single dispatch ) либо множественной (multiple dispatch ) и какого-то комбинатора методов (по типам, по условию и т.п.).

Например, опишем процесс одиночной ( single dispatch ) диспетчеризации методов в языке С++. Каждый класс имеет связанный с ним набор методов. Методы могут быть виртуальными (virtual ) или невиртуальными. Невиртуальный метод однозначно определяется типом класса – он не может быть перекрыт за счёт полиморфизма. Виртуальный метод вызывается косвенно: пусть в классе А определён виртуальный метод M1. Класс А – предок для класса B, B наследует A. В классе B определена своя реализация метода M1. Пусть определены переменные: a, проинициализированная новым объектом класса A; b,  проинициализированная объектом класса B.

 

При вызове a.M1(…) вызовется реализация A::M1, при вызове b.M1(…) – реализация B::M1.

Пусть теперь создана новая переменная c класса A таким образом:

A c =b;

Такое присваивание становится возможным благодаря полиморфизму (c с типом класса А “ведёт себя так же, как”  b с типом класса B, хотя это переменные разных типов, разных классов).

 

Что произойдёт при вызове c.M1( … ) ??

 

Если метод M1 виртуальный, то при вызове c.M1(…) вызовется B::M1(..) – не «статического» типа A, с которым объявлена переменная c, а  из-за присваивания – «динамического» типа B, определяемого во время выполнения программы.

 

Это тоже становится возможным благодаря полиморфизму.

То есть, базовый принцип полиморфизма реализуется посредством, с помощью виртуальных методов в С++.

 

В языках Java, C#, D, Delphi – все методы по умолчанию являются виртуальными. В языке С++ – программист должен заранее продумать, как будет повторно использоваться класс, и для общего поведения framework -а использовать виртуальные методы, для остальных методов в качестве оптимизации – невиртуальные (которые могут быть подставлены, inline компилятором в целях оптимизации).

 

Таким образом, реализуется механизм одиночной или множественной диспетчеризации – в языке С++ используется одиночная диспетчеризация, однозначным образом.

Например: составляется таблица виртуальных методов класса, VMT. Таблицы виртуальных методов класса-потомка и класса-наследника связаны таким образом, чтобы по сигнатуре метода класса-потомка метод можно было однозначно найти в общей таблице. Поскольку все типы, а значит, и все отношения наследования известны заранее – такую таблицу можно составить однозначно во время компиляции (см. статическую типизацию методов). Методы вызываются через указатель (VPTR) в таблице виртуальных методов (VMT, или VTable).

Другой пример: реализация объектной модели в языках SmallTalk и Objective C, а также CLOS.

 

Здесь такую таблицу заранее составить невозможно: поскольку во-первых, до момента запуска программы это неизвестно; а во-вторых, каждый класс может перекрыть метод диспетчеризации ( doesNotUnderstand: ) и выполнять диспетчеризацию по-своему.

 

Объектная модель CLOS, реализованная в языке Common Lisp поддерживает множественную диспетчеризацию методов, или мультиметоды.

Её особенности:

· Методы не принадлежат классам. Вместо этого методы представляют собой реализацию обобщённых функций (defgeneric …) , которые специализируются в конкретную реализацию конкретного класса(defmethod …).

· Сигнатура метода включает класс, и задаёт способ специализации. Так, вместо определения метода базового класса, и метода класса-потомка в определении класса, задаётся обобщённая функция и её реализации в базовом классе и классе-потомке. Модель диспетчеризации «по умолчанию» ищет наиболее подходящий, наиболее специфичный метод по сигнатуре, при этом участвуют все параметры метода (например, первый: тип класса, но также и типы всех остальных параметров). Другие, «менее подходящие» методы можно вызвать из этого с помощью call-next-method.

· Методы-комбинаторы, задающие способ поиска «наиболее специфичного метода» можно задавать произвольно, в своей программе. Например: при реализации журналирования нужно вызвать метод-действие, и записать в журнал сообщение об этом. В CLOS возможно использовать комбинаторы методов :around/:before/:after, в результате чего метод-журналирование вызовется до и после/до/после выполнения тела метода-действия. Таким же образом возможно реализовать предусловия и постусловия методов из контрактного программирования.

· Метаобъектный протокол (MOP) . Есть классы и метаклассы, и вызов метода – это посылка сообщения метаклассу. Метаобъектный протокол (помимо CLOS, присутствует также и в SmallTalk) позволяет унифицированно, единообразно стандартизировать обращение к типам свойств и методов класса, изменять их на лету во время работы программы. В других языках для похожей задачи применяется рефлексия и интроспекция, но возможности MOP более гибки.

Одиночная диспетчеризация – когда для определения наиболее специфичного метода достаточно типа одного параметра сигнатуры метода (например, типа класса, которому принадлежит метод, типа *this в C++).

Множественная диспетчеризация – когда для определения наиболее специфичного параметра используются все параметры сигнатуры метода.

 

Множественную диспетчеризацию возможно реализовать через одиночную, только более громоздко (см. реализацию функторов на С++: Александреску и т.п., библиотеки Boost, Loki и т.п.).

 

С понятиями типизации и диспетчеризации тесно связаны понятия

· Строгой типизации – когда типы всех классов, сигнатуры методов должны быть известны до компиляции

· «Утиной типизации», duck typing .
 
 «Если что-то ходит как утка, выглядит как утка, и крякает как утка – то скорее всего, это утка и есть».
Иными словами, тип класса, метод которого вызывается – неизвестен до момента выполнения программы; но предполагается, что это именно нужный класс, поскольку он обладает нужным поведением.

Пример утиной типизации – языки Visual Basic и Python. Здесь мы не можем задать тип объекта, но предполагаем, что если он обладает нужным поведением, это тот тип, который надо. Иначе во время выполнения программы возникает ошибка, исключение.

 

Дальнейшее развитие принципа наследования – одиночное или множественное наследование.

 

Одиночное наследование означает, что каждый класс-потомок может иметь только один суперкласс, класс-предок, или ни одного.

Множественное наследование допускает, что суперклассов может быть несколько.

Иными словами, класс-потомок может унаследовать поведение от нескольких классов.

 

Существуют два основных принципа композиции классов:

· Наследование ( is - A ), когда объединяются поведение и свойства базового предка в класс-потомок. Потомок для остального кода программы выглядит как базовый класс за счёт поддержки полиморфизма.

· Агрегация, или композиция,  ( has - A ) когда классы «физически» объединяются в один. То есть, новый класс, агрегат – содержит все классы и методы объединённых, или говорят, представляет собой миксин.

Миксин – это класс, который содержит все свойства и методы объединённых классов. Например, он может выступать классом-посредником (в примере с журналированием, вызывать методы объединённых классов по очереди).

 

Наследование в С++, Java, C# и т.п. – более «жёсткий тип связи». В этих языках существует проблема «хрупкости базового класса», или FBC ( Fragile Base Class problem ),  которая лучше всего иллюстрируется примером:

  • В языке Java все классы имеют базовый класс, то есть, унаследованы от класса Object. Поэтому все классы умеют распечатывать своё содержимое, реализовав объявленный в классе Object метод toString(). Допустим, сигнатура этого метода меняется: нужно распечатывать в строку с поддержкой другой кодировки. Какие требуются изменения в иерархии классов?
    • Нужно изменить сигнатуру базового класса Object.toString(int codepage)
    • Затем, изменить её во всех потомках

Возникает проблема «каскадных изменений» – одно изменение тянет за собой изменения во всех классах-потомках.

Этой проблемы в принципе не возникает в языке с поддержкой мультиметодов.

 

С другой стороны, для решения такой же задачи можно применить не наследование, а агрегацию – составить класс-миксин, который будет обворачивать (wrapping ) вызовы старого метода в новую сигнатуру.

 

Посредством миксинов можно реализовать в том числе и множественное наследование.

 

Интерфейс – это абстрактный базовый класс, который не содержит свойств и содержит только объявления методов, но не реализацию. Ему соответствует конкретный класс,  отнаследованный от интерфейса, и реализующий методы.

 

Интерфейсы позволяют программировать не в терминах классов (то есть, типов классов: «какова структура класса»), а в терминах методов (то есть, поведения: типов методов, «что надо сделать»). Конкретный класс-реализация может подставляться средой компонентного программирования (то есть, реализаций может быть несколько, и она может определяться динамически).

 

Множественное наследование классов поддерживается не всеми языками: так, оно присутствует в C++, CLOS, Eiffel, но запрещено в Java, C#, D, Delphi.

 

Потому что в С++, например, возникает проблема ромбовидного наследования:

· Пусть есть базовый класс A, его потомки B, C. В классах есть метод M(), свойство x. Пусть класс D – множественно наследует от B, C.

· Какая реализация вызовется при вызове D::M() – B::M() или C::M() ?

· D::x – это B::x или C::x ?

 

В С++ эта проблема в общем случае не решается, в CLOS, Eiffel – решается другими способами.

 

Множественное наследование интерфейсов, наоборот, разрешено во многих языках – оно не ведёт к проблеме, поскольку интерфейсы не содержат свойств (некоторые языки эмулируют наличие свойств через методы getX и setX).

 

Программирование на основе интерфейсов  является дальнейшим шагом от ООП к компонентно-ориентированному программированию (КОП).

 

Существует книга Клеменса Шиперски «Компоненто-ориентированное программирование», где на примере языка Oberon-2 (Component Pascal) были сформулированы основные принципы КОП:

· В языке поддерживается динамическая модульность, в частности, загрузка/выгрузка модулей (компонент) во время выполнения. Из этого требования вытекает необходимость поддержки сборки мусора в Oberon-2.

· Компоненты не могут зависеть друг от друга, а зависят только от интерфейсов.

· Программирование компонентной программы осуществляется на основе интерфейсов, определяемых модулями-компонентами.

 

Примерами КОП технологий являются:

· CORBA, Common Object Response Broker Architecture . Наиболее универсальна, но громоздка.

· COM, С omponent Object Model фирмы Microsoft. Компоненты не наследуются друг от друга.

· SOM, System Object Model фирмы IBM (использовалась в OS/2). Компоненты поддерживают наследование, инкапсуляцию, полиморфизм.

· .NET фирмы Microsoft. Компоненты основаны на общем стандарте CLR, поддерживаемом несколькими языками.

· BlackBox Component Pascal от учеников Никлауса Вирта, автора языка Oberon-2 (следующая версия Oberon-2, с небольшими добавлениями – Component Pascal).

· Eclipse (IDE для Java) также построен на базе компонентной технологии.

· BON, SCOOP в языке Eiffel.

· BusinessObjects в ОС NeXT (и соответственно, CoreData в MacOS X и iOS).

 

При этом среда КОП сама умеет создавать и выполнять объекты-серверы по требованию, обладающие нужным интерфейсом по запросу объекта-клиента.

 

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

 

Язык Google Go – подход ad hoc интерфейсов. В языке Go не требуется описывать, что класс реализует такой-то интерфейс; наоборот, как только класс реализует определённый метод, он автоматически реализует интерфейс, в котором определён такой метод. То есть, теперь интерфейсы находятся по классам по ситуации, ad hoc . Это заметно упрощает программирование таких процессов, как например, сериализация, реализация криптографии, ввод-вывод.


Лекция 3

Язык моделирования UML

 

Первые попытки применения моделирования к программированию возникли ещё в 1970 годы: структурный подход SDT, применяемый для разработки аппаратного обеспечения, начал применяться к задачам структурного программирования и управления проектом разработки.

Тем не менее, для ООП парадигмы ситуация долго оставалась неопределённой.

В 1985 году, Бертран Мейер изобретает язык Eiffel. Язык характеризовался полностью интегрированной средой разработки (IDE), позволяющей вести полный цикл разработки ООП приложений. Этот процесс разработки получил название «метод Eiffel»: метод описывал не только теоретические вопросы проектирования ООП систем, но и практические, такие как тестирование и отладка на основе контрактов, контрактно-ориентированное программирование, моделирование проекта архитектуры – всё из одной IDE.  В качестве нотации языка моделирования объектов предметной области использовалась нотация BON, Business Object Notation .

В 1990х появляются разные нотации языков ОО моделирования: нотация Йордона, Буча, Якобсона. Они применяются уже к более универсальным языкам программирования, таким, как C++ и SmallTalk.

Возникает потребность в некотором универсальном языке моделирования, объединяющем их преимущества.

В результате объединения нотаций Буча и Якобсона появился UML [6].

 

Язык UML развивался от версии 1.0 в середине 90х, до версии 2.0 ныне актуальной – и рассчитанной на более активную разработку на базе моделей, моделеориентированную архитектуру.

 

Понятие архитектуры программной системы начало активно употребляться в районе 1980х-1990х годов. Сначала Кристофер Александер написал работу, в которой обобщались общие принципы создания эффективных программных систем, лучшие практики реализации систем в виде набора используемых конкретных типов классов, идиом, алгоритмов, понятий. Он уподобляет проектирование сложных программных систем работе архитектора, проектировавшего здания: и там и там нужны знания лучших инженерных принципов, стандартов, теории и правил расчёта конструкции (СНиПы и сопромат; стандарты моделирования и оформления документации и паттерны проектирования), чтобы сложная конструкция не развалилась под весом собственной тяжести. Эта работа появилась ещё в 70-е годы, но была более концептуальной, и приводилось мало примеров  конкретных паттернов.

Затем, в 1990-е [7] Гамма Э., Хелм Р., Джонсон Р., Влиссидес Дж. выпускают книгу «Приемы объектно-ориентированного проектирования. Паттерны проектирования», в которой описывают сложившиеся конкретные паттерны проектирования, на примере конкретных задач и конкретных языков программирования:C++ и SmallTalk. Практическая ориентированность этой книги делает её аналогом «Искусства программирования» Дональда Кнута, описывающим «энциклопедию алгоритмов» – «энциклопедия лучших практик в ОО программировании». Подробно эта книга будет разобрана на  следующей 4 лекции.

Примерно в это же время появляется книга Гради Буча  «Объектно-ориентированные анализ, проектирование и разработка приложений» [9], в которой он на примере языка С++ описывает вопросы – уже проектирования, моделирования и описания архитектуры приложений.

 

Гради Буч также в то время работает в компании Rational (впоследствии купленной IBM), которая занимается стандартизацией языка UML, разработкой основанного на UML процесса проектирования и разработки программных систем Rational Unified Process (RUP, впоследствии просто UP), практическим применением и консультациями фирм-разработчиков по вопросам применения UML и RUP.

 

Таким образом, RUP описывает процесс разработки, основанный на UML диаграммах. В ходе этого процесса происходит следующее:

· Собираются требования к программной системе в ходе процесса управления требованиями

· Из требований выбираются нужные, важные, критичные, функциональные и нефункциональные и расставляются приоритеты

· Составляется документ «технические требования»:  что нужно сделать?

· Из него составляется документ «техническое задание»: как решить задачу?

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

· На новом этапе процессов методологии RUP диаграммы старого этапа перерабатываются в новые диаграммы, пока их набор не будет достаточен для процессов разработки.


Диаграммы UML, в свою очередь, применяются не только в методологии RUP.

 

Основное назначение диаграмм UML –  облегчение коммуникации и документирование проектных решений.

 

Для этого в нотации UML определяются следующие типы диаграмм:

· Диаграмма классов. Задаёт отношения наследования и агрегации между объектами предметной области, состав классов и методов объектов, модификаторы доступа (public/private/protected)

· Диаграмма последовательности. Аналогично циклограмме для аппаратуры, задаёт последовательность взаимодействия различных классов в виде параллельных дорожек (swim lane).

· Диаграмма взаимодействия.  Описывает ответственность и порядок взаимодействия классов при выбранном проектном решении. Также может использоваться для описания порядка взаимодействия пользователя с системой (содержит «человечков», actors)

· Диаграмма развёртывания. Содержит описание создаваемой программной системы в виде набора компонент: конечных исполняемых файлов и библиотек. Описывает распределение классов по подсистемам, и подсистем по компонентам. В случае клиент-серверной организации – ответственность и назначение компонентов при работе в сети.

· … а также другие типы диаграмм (см. [6])

 

Объекты на диаграммах связаны стрелками, которые показывают различные типы отношений.

· Наследование

· Аггрегацию

· Прочие произвольные типы отношений, подписанные на схеме (ассоциации). Например, распределение ответственности по классам.

 

 Классы группируются в пакеты (компоненты), пакеты в подсистемы, подсистемы в систему, составляющую решение.

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

 

Пример диаграммы классов UML.

 

Здесь заданы:

· Структура классов, то есть: свойства, методы, модификаторы доступа ( +: public, - : private)

· Отношение наследования: класс «Лекция» является потомком суперкласса «Занятие». Пустая стрелка проведена от класса-потомка к суперклассу.

· Отношение аггрегации: Класс «ИтоговаяОценка» включает в себя свойство «экз» класса «Экзамен».
Ромбовидная стрелка идёт от включаемого к включающему классу (агрегату).
Подпись 0..* на стрелке от Тест до ИтоговаяОценка означает, что итоговая оценка включает 0 или больше экземпляров класса тест.

 

Задачей моделирования является проектирование адекватной структуры классов, отражающей требования предметной области, и используемых базовых библиотек (framework ).

 

Моделирование начинается с задания диаграммы взаимодействия, показывающей, как пользователь  ( actor ) будет работать с системой. Используется метод сценариев использования: составляется текстовое описание (сценарий), описывающий порядок работы в системе, рисуется диаграмма взаимодействия. При этом выделяются активные сущности (actors ) – пользователи, подсистемы, внешние системы, отдельные классы. Затем из описания выделяются классы и свойства (существительные), методы классов (глаголы), определяются отношения наследования, аггрегации, ассоциации. Составляется диаграмма классов.

 

Программа для моделирования имеет возможности:

· кодогенерации по диаграмме классов , или прямой разработки
по диаграмме генерируется заготовка программного кода на выбранном языке программирования (C++/Java/C#/…), реализующая указанную на диаграмме классов структуру

·  реинжиниринга модели из кода, или обратной разработки
из кода на языке программирования генерируется диаграмма классов.

 

В дальнейшем построенная диаграмма классов может быть переработана: свойства и методы переименованы, перемещены в другой класс. Затем выполняется кодогенерация – новая структура диаграммы отражается в коде.

 

Остаётся только реализовать тело методов.

 

Этим подчёркивается моделеориентированный характер UML :  проектирование структуры программной системы, то есть, архитектуры, осуществляется на основе моделей, различного рода диаграмм.

Процесс RUP ( UP , Unified Process ) описывает методологию разработки, то есть, процесс разработки на основе этапов жизненного цикла (ЖЦ) программной системы. В ходе этого процесса выполняются подпроцессы управления требованиями, уточнения, проектирования, построения (реализации) системы, документирования, развёртывания (установки и обучения пользователей).

Стандарт XMI предназначен для обмена между различными программами моделирования диаграммами заданных типов.

 

Таким образом, в ходе работы по RUP составляется модель проекта системы, модель архитектуры.

Моделеориентированный характер UML состоит в том, что на базе модели, разработанной на предыдущем этапе ЖЦ разрабатывается новая модель.

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

Сами требования могут моделироваться.

 

Метамодель – это модель, описывающая другую модель.

DSL , или язык описания предметной области – это способ задания модели предметной области на специально сконструированном языке, адекватно отражающем понятия предметной области и отношения между ними. Это необязательно может быть «полноценный язык программирования» – например, это может быть язык описания бизнес-правил, бизнес-процессов.  Примерами таких языков, DSL являются: императивный встроенный язык 1С; декларативный язык запросов, встроенный в язык 1С; язык AutoLISP, встроенный в AutoCAD; Emacs elisp, встроенный в Emacs.

 

В современных средах разработки, таких, как Eclipse Xtext/Xtend есть инструментарий для разработки языков DSL.

Примерами сред класса language - oriented framework можно назвать JetBrains MPS, Eclipse Xtent/Xtext, Microsoft M (Oslo).

 

Моделеориентированная системная инженерия (MBSE) – разновидность системной инженерии, в которой ведётся разработка на основе моделей. В качестве моделей выступают модели архитектуры приложения, языков предметной области, моделирование требований, моделирование процесса разработки.

 

Рефакторинг – переработка кода программной системы, сохраняющая его внешнее поведение, но улучшающая внутреннюю структуру. Рефакторинг становится возможным благодаря тестированию, например, разработке через тестирование (TDD). Цель рефакторинга – улучшить архитектуру приложения, то есть, структуру технического решения, сохранив внешнее поведение системы.

 

В ходе лабораторной работы мы рассмотрим проектирование диаграммы классов, диаграммы последовательности, прямую и обратную разработку, кодогенерацию в программе моделирования  UML Enterprise Architect на примере учебной задачи.

 

Лекция 4

Паттерны проектирования

 

 

Понятие архитектуры программной системы начало активно употребляться в 1980х-1990х годах. Сначала Кристофер Александер написал работу, в которой обобщались общие принципы создания эффективных программных систем, лучшие практики реализации систем в виде набора используемых конкретных типов классов, идиом, алгоритмов, понятий. Он уподобляет проектирование сложных программных систем работе архитектора, проектировавшего здания: и там и там нужны знания лучших инженерных принципов, стандартов, теории и правил расчёта конструкции (СНиПы и сопромат; стандарты моделирования и оформления документации и паттерны проектирования), чтобы сложная конструкция не развалилась под весом собственной тяжести. Эта работа появилась ещё в 70-е годы, но была более концептуальной, и приводилось мало примеров.

В 1990-е годы Гради Буч пишет книгу «Объектно-ориентированный анализ и проектирование приложений» с примерами на С++ [9], где обобщает «теорию ОО проектирования» на С++.

Затем, в 1990-е [7] Гамма Э., Хелм Р., Джонсон Р., Влиссидес Дж. (самоназвание: «Банда четырёх») выпускают книгу «Приемы объектно-ориентированного проектирования. Паттерны проектирования», в которой описывают сложившиеся конкретные паттерны проектирования, на примере конкретных задач и конкретных языков программирования:C++ и SmallTalk. Практическая ориентированность этой книги делает её аналогом «Искусства программирования» Дональда Кнута, описывающим «энциклопедию алгоритмов» – «энциклопедия лучших практик в ОО программировании». Подробно эта книга будет разобрана на этой  лекции.

 

 

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



2019-11-13 234 Обсуждений (0)
Современное состояние языков программирования. 0.00 из 5.00 0 оценок









Обсуждение в статье: Современное состояние языков программирования.

Обсуждений еще не было, будьте первым... ↓↓↓

Отправить сообщение

Популярное:
Почему люди поддаются рекламе?: Только не надо искать ответы в качестве или количестве рекламы...
Почему двоичная система счисления так распространена?: Каждая цифра должна быть как-то представлена на физическом носителе...



©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (234)

Почему 1285321 студент выбрали МегаОбучалку...

Система поиска информации

Мобильная версия сайта

Удобная навигация

Нет шокирующей рекламы



(0.011 сек.)