Файл: Применение объектно-ориентрованного подхода при проектировании информационной системы (Объектный подход при разработке программ).pdf
Добавлен: 28.03.2023
Просмотров: 67
Скачиваний: 2
Поэтому в рамках проекта нецелесообразно разрабатывать класс, а потом единожды его использовать, только в рамках одного проекта. Разработка класса оправдывает себя только в том случае, если в последствие предполагается его использование во множестве проектов [7]. Из чего следует, что работа по разработке класса должна являться отдельным проектом, с прицелом на коммерческую реализацию класса или дальнейшее многократное его использование при разработке других проектов софтверной компании.
Но для людей, которые используют, кем-то ранее написанный класс, возникают трудности, связанные с непониманием функционирования и внутреннего устройства класса. Класс представляется, для использующего его программиста, как «черный ящик» с кое-как описанными интерфейсами. За редким исключением, класс всегда избыточен и содержит множество не нужных для конкретного проекта, методов и переменных, которые расходуют (уже не столько, но все-таки) драгоценную память. Хорошо, если модуль класса является неоткомпилированным и программист может (при наличии времени и желания) разобраться с его устройством и тем самым избежать ошибок при его использовании.
Особую опасность объектно-ориентированный подход к программированию, представляет при разработке программ, управляющих аппаратными средствами. Так как программист не может знать, какие именно аппаратные ресурсы затребует используемый им класс, и не конфликтуют ли, запрашиваемые классом, ресурсы с другим используемым классом. Подобная ошибка программирования может стать причиной многочисленных человеческих жертв, технических и технологических катастроф.
По этой причине объектный подход для разработки управляющих программ для аппаратных устройств применяется значительно реже, чем при разработке программ офисного назначения [23]. Еще одним недостатком объектного подхода для разработки драйверов устройств является избыточность кода и как следствие низкая его производительность по сравнению с процедурным подходом с применением языков более низкого уровня, не имеющих объектных возможностей (Си, Ассемблер и т.п.) [16].
Основной подход к разработке объектно-ориентированных программ заключается (так же как и процедурно-ориентированный) в разбиении стоящей задачи на более простые подзадачи, до того момента пока, задачи не станут совсем элементарными. Элементарные операции оформляются в виде отдельных методов конкретного класса. Классы должны объединять методы и данные определенного функционального назначения. В идеале класс должен представлять собой «вещь в себе», т.е. отдельный независимый объект, который может быть использован в любом проекте, независимо от остальных классов текущего проекта [7].
Таким образом, разработка объектно-ориентированной программы с нуля мало чем отличается от разработки процедурно-ориентированной. Абстрагирование начинается только тогда, когда программист использует уже готовые классы. Абстрагирование – это попытка скрыть от программиста реальное внутреннее устройство класса и принцип его работы, представив его как виртуальный аналог объекта реального мира [1]. Зачем это нужно? Автор затрудняется дать ответ на этот вопрос, так как это идет в разрез с основным принципом программирования, согласно которому, текст программы должен быть максимально понятным, читабельным и простым. Отсутствие у программиста понимания, как работает его программа, ни к чему хорошему не приведет.
Однако абстрагирование действительно упрощает процесс программирования для неспециалистов, позволяя обращаться с виртуальными объектами, как с объектами реального мира. Для манипуляции абстрактными виртуальными объектами не нужен специалист высокого уровня, что позволяет снизить фонд заработной платы и значительно сократить время разработки проекта.
Например, обращение к методам класса, представляющего собой абстрактный датчик атмосферных параметров, с целью получить значение температуры в градусах Цельсия, может сводиться к записи:
ДатчикАтмостферныхПараметров.Температура.Цельсия
Т.е. для получения нужных данных через абстрактный класс, описывающий датчик атмосферных параметров, пользователь класса может, с использованием, т.н., операции «точка», получить интересующую его информацию. В действительности же процесс получения данных с реального датчика, при использовании процедурного программирования, может выглядеть как-то так (приложение 1).
Если функции процедурного программирования на этапе проектирования принято описывать с использованием блок-схем алгоритмов, то для графического описания внутреннего устройства объектов (классов) больше подходит универсальный язык моделирования – UML [6].
UML - (англ. Unified Modeling Language — унифицированный язык моделирования) — язык графического описания для объектного моделирования в области разработки программного обеспечения, для моделирования бизнес-процессов, системного проектирования и отображения организационных структур (рисунок 5).
Рисунок 5. UML-диаграмма классов
Эффективность применения языка UML в реальной действительности вызывает сильные сомнения. Дело в том, полностью описать созданный проект с помощью UML невозможно, так как на это нужно затратить огромные усилия, большое количество времени и финансовых затрат. Кроме того, во время разработки проекта, UML-диаграммы придется постоянно обновлять, чтобы привести их в соответствие с реальной реализацией объектов проекта, которая редко совпадает с первоначально задуманной и постоянно меняется по ходу проекта. По завершению проекта документ, содержащий UML-диаграммы объектов, будет иметь просто огромный размер, в несколько раз превышающий текст исходного кода проекта на языке программирования высокого уровня.
Такими же недостатками обладают блок-схемы алгоритмов, которые использовались для описания процедурно-ориентированных модулей программ, поэтому они редко применялись на практике, а если и применялись, то описывали лишь общий принцип функционирования, далекий от алгоритма, реально реализованного в программном модуле.
Использование языка UML для проектирования объектов, можно сравнить с программой для виртуальной машины Тьюринга [22], которая в действительности не имеет практической ценности, а интересна лишь энтузиастам.
Из вышесказанного можно сделать следующий вывод, что объектный подход к разработке проекта сокращает время на разработку, экономит финансы (на этапе разработки), но несет риски, связанные с плохим пониманием разработчика нюансов функционирования блоков из которых собран проект.
2. Предпосылки появление объектного проектирования
Концепция блочного, модульного построения машин, космических аппаратов, приборов и даже зданий давно используется в мире [15]. С появлением такого вида человеческо деятельности, как разработка компьютерных программ, желание упростить процесс программирования, путем использования готовых блоков (модулей, объектов) является вполне естественным.
Первые попытки подобного упрощения процесса программирования были предприняты немцем Конрадом Цузе, который в 1945 году создал первый язык программирования высокого уровня и дал ему название - Планкалкюль (нем. Plankalkül — исчисление планов). Однако язык не имел интерпретатора и не мог использоваться по назначению [35]. Следующий пример показывает программу на языке Планкалкюль, которая вычисляет максимум из трёх переменных, вызовом функции max3:
P1 max3 (V0[:8.0],V1[:8.0],V2[:8.0]) → R0[:8.0]
max(V0[:8.0],V1[:8.0]) → Z1[:8.0]
max(Z1[:8.0],V2[:8.0]) → R0[:8.0]
END
P2 max (V0[:8.0],V1[:8.0]) → R0[:8.0]
V0[:8.0] → Z1[:8.0]
(Z1[:8.0] < V1[:8.0]) → V1[:8.0] → Z1[:8.0]
Z1[:8.0] → R0[:8.0]
END
Широкое распространение языков высокого уровня началось с 1957 года, когда группой программистов под руководством Джона Бэкуса в корпорации IBM был создан язык Fortran [19]. Название Fortran является сокращением от FORmula TRANslator (переводчик формул). Пример программы вычисления факториала на языке FORTRAN:
program Factorial
integer :: f,n
f = 1
n = 0
do
print "(I2, A, I10)", n, "! = ", f
n = n + 1
f = f * n
if (n == 17) then
exit
end if
end do
end program Factorial
Главным преимуществом языков высокого уровня является абстракция, т.е. абстрагирование программиста от действий, которые реально происходят на уровне машинного кода и приближение записи компьютерной программы к более понятному для человека виду. Таким образом, программа, написанная на языке, понятном для человека заменяется блоками команд машинного кода в процессе трансляции. Программист, пишущий программу на языке высокого уровня, манипулирует не отдельными машинными кодами, а целыми группами (операторами, объектами) [3].
Это позволяет сократить время разработки программ и использовать менее квалифицированный персонал, не обладающий знанием внутреннего устройства вычислительной машины и навыками программирования в машинных кодах.
За полученные преимущества приходится расплачиваться увеличением времени работы программы и большим расходованием памяти, занимаемой программой и ее переменными. Это связано с тем, что блоки кодов, которыми оперирует программист, являются максимально универсальными и содержат большое количество не нужных для конкретной ситуации машинных кодов, но которые все равно будут размещены в памяти при переводе программы с языка высокого уровня в машинный код [8].
Следует иметь в виду, что сокращение расходов на разработку программы может обернуться излишними расходами на ее поддержку. Так как использование программистом кусков чужого кода, не позволяет полностью понять как будет функционировать готовый продукт. Это повышает вероятность того, что через определенно время эксплуатации, пользователями будут обнаружены ошибки, которые программист не мог выявить на стадии разработки, по причине незнания всех особенностей функционирования объектов, которые он использовал.
В качестве примера можно привести ситуацию, возникшую на планете с появлением процессоров Pentium. Оказалось, что программы, написанные на языке Borland Pascal (1992 года выпуска), не могут запуститься на этом процессоре. Причиной этого стала ошибка в функции Delay модуля CRT [41], которая использовалась во всех, без исключения программах, написанных на языке Borland Pascal. Для исправления ситуации фирма Borland (разработчик языка Borland Pascal) выпустила специальную программу, которая исправляла ошибку в уже откомпилированных программах, созданных на языке Borland Pascal. Эта ситуация стала причиной больших финансовых потерь для компаний эксплуатирующих ПО, написанное с использование высокоуровневого языка от фирмы Borland.
Однако капиталистическое, конкурентное устройство экономик большинства стран планеты не оставляет производственным компаниям выбора. Производимый продукт должен создаваться в кратчайшие сроки и с минимальной себестоимостью [21].
Ситуация вынуждает вводить все новые и новые уровни абстракции в процесс разработки программ, делая процесс все более простым и быстрым, но все менее понятным (на низком уровне) для разработчика.
Следующим уровнем абстракции, после языков высокого уровня, стало появление объектно-ориентированных языков программирования. В объектно-ориентированном языке объект (класс), использующийся для создания программы, должен быть максимально приближен к объекту реального мира (а не к архитектуре компьютера) и должен быть максимально независим от других объектов. Именно такая философия была заложена в язык Simula [1], в котором впервые было введено понятие объекта. Так, например, программа управления автомобилем может состоять из объектов: Двигатель, Салон, Колеса. Эти объекты могут быть составными частями более общего класса: Автомобиль. В таком случаем для включения двигателя автомобиля программисту будет достаточно написать следующих код:
Автомобиль.Двигатель.Запустить
Из представленного примера можно видеть, что для создания программ с использованием объектно-ориентированного подхода не требуется высокой квалификации от программиста. Разработкой программ подобного типа может заниматься даже ребенок. Однако подобный подход полностью скрывает от разработчика огромную сложность машинного кода, спрятанного за абстрактными объектами.
Программы, написанные на языках высокого уровня, имеют одно очень важно преимущество, перед программами, написанными на низкоуровневых языках – это переносимость программы между компьютерами с разными архитектурами [3]. Так программа, написанная на компьютере с центральным процессором фирмы Intel, может быть легко откомпилирована для компьютера с другим центральным процессором. Провернуть подобный трюк с программами, написанными на языках низкого уровня невозможно т.к. они манипулируют машинными кодами того процесса, для которого были написаны [13].
Однако данное преимущество не позволяет запускать программы на разных операционных системах, т.е. программа, написанная для ОС Windows, не может быть запущена в ОС Unix, без использования специального эмулятора. Причиной этого является то, что во время работы программы интенсивно используют функции операционной системы: вывод на экран, обращение к устройствам хранения данных, вывод данных на периферийные устройства и т.п. За перечисленные функции отвечает операционная система и в разных ОС эти функции реализованы по-разному [11].