Автор Анна Евкова
Преподаватель который помогает студентам и школьникам в учёбе.

Применение объектно-ориентрованного подхода при проектировании информационной системы (Объектный подход при разработке программ)

Содержание:

Введение

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

Есть ли на планете человек знающий устройство и принцип работы хотя бы одной современной микросхемы?

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

Для специалистов, работающих в соответствующих областях, ответ на заданные выше вопросы очевиден – нет!

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

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

Современный подход к разработке продуктов с использованием, так называемых, CASE-технологий [28] все больше отдаляет инженера от понимания принципов работы, создаваемых им изделий. Современный инженер не понимает принципов работы объектов, которыми он манипулирует (как кубиками «LEGO»). Стоит ли говорить о том, что подобный подход к производству рано или поздно приведет к непоправимым последствиям.

В настоящее время можно наблюдать печальные результаты такого подхода к проектированию. Это проявляется в относительно безобидных программных ошибках в популярных пакетах офисных компьютерных программ и в серьезных, техногенных происшествия и технических катастрофах с огромным количеством человеческих жертв [45].

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

Настоящая работа не будет затрагивать банальные, хорошо исследованные темы объектных (классовых) языков программирования (C#, UML, SмallTalk и т.п.), а сосредоточена на опасностях, которые обязательно возникнут перед «объектно-ориентрованным» человечеством в будущем.

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

Вторая глава описывает предпосылки появления объектного проектирования в недалеком прошлом (именно в такой последовательности, тут нет ни какой ошибки в логике повествования!).

Третья глава подробно описывает опасности объектного проектирования, которые уже приводят и будут будущем в будущем к трагическим последствиям.

Литературы, посвященной опасности объектного подхода в проектирования, не просто мало, а ее вообще нет на книжном рынке, поэтому большая часть использованных источников информации по главной теме повествования являются сетевыми ресурсами. Описание принципов объектного подхода при проектировании ПО основано на книгах М. Вайсфельда [7] и Г. Буча [5].

Настоящая работа затрагивает проблемы не только объектного (модульного, классового, шаблонного) способа разработки программ, но и объектного способа разработки электронных, механических и других изделий, тем самым показывая, что модульность является тенденцией современного производства, описание этого изложено в книге В.Н. Княгинина [15] и в статьях сайта kmpu.ru [36].

Понятия «модуль» и «объект» в настоящей работе являются равнозначными.

1. Принципы объектного проектирования

1.1. Объектный подход при разработке электроники

В настоящее время имя «ардуино» (“arduino”) уже является нарицательным. Модульная технология создания электронной и роботизированной техники, разработанная в Италии, преподавателем местного института города Ивреа, Массимо Банци, получила всемирное распространение. Мотиватором к созданию технологии послужило желание М. Банци создать дешевую платформу для обучения своих студентов программированию электронных устройств. Уже существующие на том момент электронные платформы, были слишком дороги для обеспечения ими каждого студента [4].

Технология, разработанная Банцы представляла собой электронную плату, с дешевым микроконтроллером (ATmega328 [2]), Си++-подобным, объектным языком программирования, средой разработки (Arduino IDE) и огромным количеством готовых библиотек (классов, объектов, паттернов) для быстрого написания управляющих программ и подключения к плате наиболее распространенных, недорогих датчиков и исполнительных механизмов, рисунок 1.

Первая arduino Arduino Uno

Рисунок 1. Первый прототип платы «Arduino» (слева), коммерческий вариант платы «Ардуино» (справа)

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

Со временем многие фирмы начали выпускать ардуино-совместимые модули со стандартными интерфейсами подключения (UART, 1-wire, I2C, SPI [14]) и конструирование техники на основе «Ардуино» стало тривиальной задачей [12], которая по силам даже детям, рисунок 2.

C:\Users\user\Desktop\keyestudio-sensor-kit-36-in-1.jpg

Рисунок 2. Модули для подключения к плате «Adrduino»

Простота разработки устройств на основе «Ардуино» не говорит о том, что технология предназначается только для детей или для непрофессионалов. На основе данной технологии разрабатываются достаточно серьезные проекты, к которым относятся: космические аппараты, планетоходы, системы автоматизированного управления, летательные аппараты, робототехника и многое другое [34], рисунок 3.

https://i.pinimg.com/236x/be/eb/18/beeb18c7e55cefe908b08309b77f4687--experiment-math-resources.jpg

Рисунок 3. Микро-спутник, созданный на «Ардуино»

Модульный подход к разработке электронных устройств отличается от модульного подхода к разработке программного обеспечения. Если программист имеет возможность создать недостающий модуль самостоятельно (для этого нужен только язык программирования и компьютер), то разработчик электроники манипулирует только имеющимися модулями, самостоятельно разработать и произвести недостающую микросхему разработчик электроники не может [36].

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

Естественно, что ни программист, использующий объектный подход программирования, ни человек, занимающийся модульным созданием электронных устройств, не понимают особенностей функционирования блоков, на основе которых они строят свою разработку [39]. Эти особенности функционирования блоков могут не проявлять себя значительное время, и даже могут быть не выявлены на стадии тестирования. Так, например, разработчикам устройств на «Ардуино» хорошо известна проблема нехватки ресурсов, когда разные устройства пытаются воспользоваться одним и тем же узлом микроконтроллера (например, каналом таймера), что приводит к сбою работы всей системы [4].

Если управляющая программа для проекта была написана от начала до конца одним разработчиком, им бы были учтены многие проблемы, которые могут возникнуть во время эксплуатации устройства. Однако модульное программирование не дает такой возможности [20]. Даже заметив ошибку в работе программы или устройства, модульный разработчик не сможет ее устранить, не обладая соответствующими навыками программирования, а если проблема связана с аппаратной частью, то в большинстве случаев, она вообще не устранима и ее приходится обходить программными методами или начинать разработку с нуля, использую другие аппаратные средства.

Модульная разработка устройств и программ, кроме очевидных различий, имеет некоторые сходства в части интерфейсов передачи данных между объектами. В обоих случаях они стандартизированы. Как известно, передача данных между методами класса (объекта) осуществляется либо через стек, либо через глобальные переменные или константы, либо через файл или сеть [13].

Передача данных между объектами модульных электронных устройств также осуществляется через широко-распространенные каналы связи: UART, I2C, 1-WIRE, SPI, JTAG и их модификации: RS-232, RS-485, RS-422, USB, USART, SBUS, CAN и др.

Каждый вид связи программных и аппаратных модулей имеет свои преимущества и недостатки. Переполнение стека, выход за границы защищенной области памяти, несоответствие размеров данных, превышение времени тайм-аута ожидания сети, переполнение устройств хранения данных – это лишь некоторые из причин, которые могут вызвать сбой при передачи данных от одного программного модуля к другому [13].

Обрыв лини связи, электромагнитные помехи, плохой контакт, дребезг контактов, неполное соответствие протоколов, слишком короткая или слишком длинная проводная линия передачи данных, отражение сигнала от концов линии, неподходящие погодные условия, электромагнитные наводки соседних электрических проводников - это далеко не полный список причин, которые могут вызвать нарушение передачи данных между электронными модулями [14].

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

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

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

Рисунок 4. Абстрактное модульное электронное устройство

1.2. Объектный подход при разработке программ

Цель, которую преследовали, разработчики объектно-ориентированного подхода в программировании ясна – упростить и укорить разработку программных продуктов, тем людям, которые будут использовать уже готовые, созданные кем-то ранее, классы [1].

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

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

2. Возможность избежания конфликта имен переменных и функций (методов) классов, которые нельзя устранить при процедурном программировании, если используется уже откомпилированный модуль.

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

Поэтому в рамках проекта нецелесообразно разрабатывать класс, а потом единожды его использовать, только в рамках одного проекта. Разработка класса оправдывает себя только в том случае, если в последствие предполагается его использование во множестве проектов [7]. Из чего следует, что работа по разработке класса должна являться отдельным проектом, с прицелом на коммерческую реализацию класса или дальнейшее многократное его использование при разработке других проектов софтверной компании.

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

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

По этой причине объектный подход для разработки управляющих программ для аппаратных устройств применяется значительно реже, чем при разработке программ офисного назначения [23]. Еще одним недостатком объектного подхода для разработки драйверов устройств является избыточность кода и как следствие низкая его производительность по сравнению с процедурным подходом с применением языков более низкого уровня, не имеющих объектных возможностей (Си, Ассемблер и т.п.) [16].

Основной подход к разработке объектно-ориентированных программ заключается (так же как и процедурно-ориентированный) в разбиении стоящей задачи на более простые подзадачи, до того момента пока, задачи не станут совсем элементарными. Элементарные операции оформляются в виде отдельных методов конкретного класса. Классы должны объединять методы и данные определенного функционального назначения. В идеале класс должен представлять собой «вещь в себе», т.е. отдельный независимый объект, который может быть использован в любом проекте, независимо от остальных классов текущего проекта [7].

Таким образом, разработка объектно-ориентированной программы с нуля мало чем отличается от разработки процедурно-ориентированной. Абстрагирование начинается только тогда, когда программист использует уже готовые классы. Абстрагирование – это попытка скрыть от программиста реальное внутреннее устройство класса и принцип его работы, представив его как виртуальный аналог объекта реального мира [1]. Зачем это нужно? Автор затрудняется дать ответ на этот вопрос, так как это идет в разрез с основным принципом программирования, согласно которому, текст программы должен быть максимально понятным, читабельным и простым. Отсутствие у программиста понимания, как работает его программа, ни к чему хорошему не приведет.

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

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

ДатчикАтмостферныхПараметров.Температура.Цельсия

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

Если функции процедурного программирования на этапе проектирования принято описывать с использованием блок-схем алгоритмов, то для графического описания внутреннего устройства объектов (классов) больше подходит универсальный язык моделирования – UML [6].

UML - (англ. Unified Modeling Language — унифицированный язык моделирования) — язык графического описания для объектного моделирования в области разработки программного обеспечения, для моделирования бизнес-процессов, системного проектирования и отображения организационных структур (рисунок 5).

https://prog-cpp.ru/wp-content/uploads/classdiagram.png

Рисунок 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].

Таким образом, переносимость возможна лишь для программ, написанных для устройств, не имеющих операционной системы, либо для программ, написанных для специальных эмуляторов, установленных в ОС: Java Virtual Machine [32], NodeJS [10] и др.

Очередной уровень абстракции представлен сверхвысокоуровневыми языками программирования (англ. very high-level programming language, VHLL). В отличие от языков программирования высокого уровня, где описывается принцип «как нужно сделать», в сверхвысокоуровневых языках программирования описывается лишь принцип «что нужно сделать». Таким образом, программист полностью избавляется от необходимости понимания как функционирует компьютер, периферийные устройства, сеть и операционная система, а нанимающая его на работу компания, устанавливает ему соответствующую (низкую) заработную плату.

Примером языка очень высокого уровня абстракции является язык Icon [31], разработанный Ральфом Э. Грисволдом. Icon — язык программирования, унаследовавший идеологию более раннего языка SNOBOL [9]. Название языка является сокращением от слова англ. iconoclastic (иконоборческий), используемом в смысле борьбы с конформизмом в разработке языков программирования.

К современным, наиболее известным VHLL-языкам программирования, с некоторыми оговорками, можно отнести: Haskell [17], Python [29], Ruby [24] и некоторые другие.

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

Концепция модульного построения устройств – это один из принципов построения радиоэлектронной аппаратуры. Суть ее заключается в том, что любой аппарат представляется в виде набора отдельных независимых модулей, связанных между собой проводными или электромагнитными (оптическими, радио) соединениями. Парадигма состоит в том, что модули являются относительно универсальными и могут быть применены в других аппаратах без изменений печатной платы. Благодаря этому время на разработку всего аппарата существенно сокращается, т.к. изделие собирается из уже имеющихся запчастей, т.е. заранее разработанных модулей [36].

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

http://www.thg.ru/mainboard/20051112/images/platform-intro.jpg

Рисунок 6. Печатная плата IBM-совместимого компьютера с установленными модулями

Покупатели модульных компьютеров могут самостоятельно выбирать комплектующие исходя из своих финансовых возможностей или рабочих потребностей [27].

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

Современная индустрия постоянно находится в процессе перехода от интегрированного к модульному принципу производства продукции, что хорошо показываем схема, представленная на рисунке 7 (Источник: ЦСР «Северо-Запад» по модели Utterback). Стрелками показано стремление отрасли производства к модульности [15].

Рисунок 7. Переход от интегрированной архитектуры к модульной архитектуре для различных отраслей производства

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

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

Подводя итого можно сказать, что предпосылками к созданию объектно-ориентрованного подхода к проектированию устройств, машин, строений, программного обеспечения и информационных систем послужили - стремление компании-разработчика получит максимальную прибыль в кротчайшие строки. То есть, предпосылками являются буржуазно-капиталистическое устройство экономик стран. Что является вполне естественным, если обратиться к работам К. Маркса [18].

3. Опасности объектного проектирования

Основные опасности объектного подхода к проектированию информационных систем (и не только информационных), уже кратко упоминались в предыдущих главах:

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

2. Отток профессиональных специалистов из области разработки информационных систем из-за снижения заработной платы и как следствие, появление на рынке систем низкого качества, эксплуатация которых будет приводить не только к финансовым потерям, но и к человеческим жертвам, техническим и техногенным катастрофам;

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

Из всего выше перечисленного наибольшую опасность представляет третий пункт. Количество, только известных, ложных срабатываний информационных систем предупреждения о ядерном ракетном ударе в США, поражает. Причем по мере автоматизации систем предупреждения, количество ложных срабатываний начинает возрастать, к 1979—1980 гг. возрастает до нескольких срабатываний в сутки. В журналах боевого дежурства офицеров на пункте управления Командованием воздушно-космической обороны Северной Америки в Шайенн-маунтин в первой половине 1980 года регистрируется свыше десяти случаев срабатывания системы предупреждения в сутки [42].

26 сентября 1983 — на пункт управления системы предупреждения о ракетном нападении пришли данные о запуске с территории США ядерных ракет по Советскому Союзу. В 1993 году стало известно, что атака была признана ложной решением оперативного дежурного подполковника С. Е. Петрова [30].

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

Компании-разработчики информационных систем будут экономить на фонде заработной платы сотрудников, но увеличат расходы на поддержку. Риск, связанный с гибелью людей, вероятностью техногенной или технической катастрофы, по все видимости, не пугает девелоперов. Кроме того в капиталистическом мире действует принцип «Too big to fail» - это разговорный термин, приписываемый экономисту Хайману Мински, обозначающий компании, настолько большие и имеющие такое количество экономических связей, что их банкротство будет иметь катастрофические последствия для экономики в целом [25]. Согласно этому принципу банкротство не грозит, таким компаниям как:

- Microsoft (капитализация 905 млрд долларов);

- Apple (капитализация 896 млрд долларов);

- Amazon (капитализация 875 млрд долларов);

- Alphabet (капитализация 817 млрд долларов);

- Berkshire Hathaway (капитализация 494 млрд долларов);

- Facebook (капитализация 476млрд долларов);

- Alibaba (капитализация 472 млрд долларов);

- Tencent (капитализация 438 млрд долларов) и многим другим [47].

К каким бы убыткам и к каким бы последствиям для планеты не привели ошибки этих компаний, обанкрочены они не будут.

Ниже приведен список только наиболее известных серьезных последствий, вызванных ошибками в проектировании информационных систем, взятый из статьи «Топ-6 катастроф, произошедших «по вине» программного обеспечения» журнала «Популярная механика» [46]:

- 4 июня 1996 года Европейское космическое агентство запустило ракету Ariane 5., ошибка в программном обеспечении модуля управления привела к самоуничтожению ракеты через 37 секунд после взлета. Стоимость одного пуска Ariane 5 составляет порядка 140-150 млн долларов [43];

- В 2013 году сбой программы почти довел инвестиционную компанию Knight Capital до банкротства. Фирма потеряла 440 миллионов долларов за 40 минут из-за того, что компьютеры стали покупать и продавать миллионы акций безо всякого человеческого контроля. В итоге цены на акции компании упали на 75% за два дня. Компания была спасена от банкротства (она слишком большая, чтобы обанкротиться, хотя капитализация компании составляет всего $700-800 млн. [44]);

- В 1980-е годы пять пациентов умерли после получения большой дозы рентгеновского излучения в результате программной ошибки блока управления установкой лучевой терапии Therac-25. Как полагают эксперты, сбой был вызван ошибкой в коде, в результате которой программа пыталась выполнять одну и ту же команду многократно. Справедливости ради, стоит сказать, что программа, убившая людей, была написана не по объектному принципу, а на языке ассемблера, однако рентгеновский аппарат, которым управляла программа, был собран из блоков, изначально не предназначенных для совместной работы и компьютерного управления [40];

- Отключение серверов Amazon летом 2013 года лишило многих людей их данных, хранившихся в «облаке». Авария, изначально вызванная сильной грозой, усугубилась внезапно обнаруженными программными ошибками, в результате чего произошел каскадный сбой. Это далеко не первый сбой серверов Amazon, поэтому компания имеет специальное соглашение, по которому она выплачивает всем пострадавшим денежную компенсацию [37];

- Массовое отключение электроэнергии в США в 2003 году стало результатом локальной аварии, которая осталась незамеченной из-за ошибки программного обеспечения для мониторинга работы оборудования General Electric Energy, и также привела к масштабному каскадному сбою. Для примера, слайд в приложении 2 иллюстрирует финансовые потери только в США от отключения энергии в 2015 году (по данным www.sandc.com), они составили 52 миллиарда долларов [48];

- В 2014 году программная ошибка вынудила совершить посадку всего воздушного флота авиакомпании American Airlines. Сбой в системе бронирования билетов возник после объединения двух информационных систем с целью слияния нескольких авиакомпаний.

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

Агентно-ориентированный подход (далее АОП) является частным случаем (специализацией) объектно-ориентированного программирования (далее ООП). В АОП объекты называется – агентами. В ООП вычислительный процесс понимается достаточно широко как система, собранная из объектов, которые взаимодействуют друг с другом через сообщения (передачу параметров от метода к методу). АОП специализирует эти понятия, устанавливая состояние объектов (агентов). Агенты состоят из компонентов: «верование», «способности» и «решения». Каждый компонент обладает определенным синтаксисом [26].

Вычисления в АОП состоят из информирования агентов, выполнения их требований, выполняя их предложений, принятий отклонений, конкуренций между агентами и помощи одного агента другому агенту. [33].

Итак, если в ООП программист оперирует объектами, то в АОП оперирование осуществляется агентами, в качестве которых могут выступать обученные нейронные сети.

За доказательством опасности такого подхода к программированию далеко ходить не надо, возьмем, для примера, широко известную автомобильную компанию Tesla, выпускающую автомобили с автопилотом, в основе функционирования которого лежат обученные нейронные сети (агенты, объекты). В настоящее время на счету автопилота следующие катастрофы [38]:

- в марте 2016 года автопилот Tesla проехал под грузовиком, оторвав крышу и убив водителя Джереми Берен Бэннера, возрастом 50 лет (водитель грузовика не пострадал);

- 7 мая 2016 года 40-летний Джош Браун погиб при таких же обстоятельствах. (водитель грузовика не пострадал);

- в 2018 году три Tesla врезались в стоящие пожарные машины (без серьезных травм для водителей);

- 14 мата 2019 года Tesla врезалась в угол стоящей «Газели», автомобиль Tesla сгорел, водитель, 41-летний Алексей Третьяков, получил переломы ноги и носа, а его несовершеннолетние дети отделались ушибами;

- в марте 2018 года, инженер Apple Вэй Лун Хуанг разбился на Tesla Model X, когда машина с включенным автопилотом врезалась в дорожное ограждение.

В общей сложности в 2018 году в авариях с участием Tesla погиб 21 человек, в 2019 году – уже 50.

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

.

Заключение

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

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

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

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

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

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

Учитывая тот факт, что люди всегда умирают, возникает вопрос - знает ли кто-нибудь, как устроена система ответного ядерного удара?

Список использованной литературы

1. Андрианов А. Н., Бычков С. П., Хорошилов А. И , Программирование на языке симула-67, издательство Наука, 1985 - 288 c.

2. Белов А.В. Микроконтроллеры AVR. От азов программирования до создания практических устройств, Издательство: Наука и Техника, 2016 – 554 с.

3. Бен-Ари М., Языки программирования. Практический сравнительный анализ, Издательство Мир, 2000 – 336 с.

4. Блум Д., Изучаем Arduino. Инструменты и методы технического волшебства, Издательство: БХВ-Петербург, 2018 – 336 с.

5. Буч Г., Максимчук Р. А., Энгл М. У., Янг Б. Д., Коналлен Д., Хьюстон К. А., Объектно-ориентированный анализ и проектирование с примерами приложений, издательство: Вильямс, 2017 – 720 с.

6. Буч Г., Рамбо Д., Якобсон А., Язык UML. Руководство пользователя, Издательство ДМК Пресс, 2007 – 496 с.

7. Вайсфельд М., Объектно-ориентированный подход, Издательство: Питер, 2020 – 256 с.

8. Голицына О. Л., Попов И. И., Программирование на языках высокого уровня, издательство Форум, 2010 – 496 с.

9. Грисуолд Р.; Поудж Дж.; Полонски И., Язык программирования СНОБОЛ -4, издательство Мир, 1980 - 270 с.

10. Дейли Б., Дейли Б., Дейли К., Разработка веб-приложений с помощью Node.js, MongoDB и Angular., издательство Вильямс, 2020 – 656 с.

11. Джонсон Х., Системное программирование в среде Windows, Издательский дом Вильямс, 2005 – 514 c.

12. Иго Т., Arduino, датчики и сети для связи устройств, издательство: БХВ-Петербург, 2015 - 544 с.

13. Ирвин К. Р. , Язык ассемблера для процессоров Intel, издательство: Вильямс, 2005 - 912 с.

14. Ключев А.О., Ковязина Д.Р., Петров Е.В., Платунов А.Е. Интерфейсы периферийных устройств. – СПб.: СПбГУ ИТМО, 2010. – 290 с.

15. Княгинин В.Н. Модульная революция: распространение модульного дизайна и эпоха модульных платформ: учеб. пособие / под ред. М. С. Липецкой, С. А. Шмелевой. – СПб., 2013. — 80 с.

16. Комиссарова В., Программирование драйверов для Windows, Издательство: БХВ-Петербург, 2007 - 253

17. Курт У., Программируй на Haskell, издательство ДМК Пресс, 2019 – 648 с.

18. Маркс К., Капитал, издательство Книжная лаборатория, Лениздат, 2018 – 512 с.

19. Маркус А., Современный Fortran на практике, издательство ДМК Пресс, 2015 – 308 с.

20. Мессенбок Х, Плюсы и минусы объектно-ориентированного программирования, М., ИнфоАрт, 1998 – 278 с.

21. Пивкин С. А., Статья. Себестоимость инновационного продукта: калькулирование и прогноз. Международный бухгалтерский учет. 2016. № 10. С. 21-34.

22. Пильщиков В.Н., Абрамов В.Г., Вылиток А.А., Горячая И.В., Машина Тьюринга и алгоритмы Маркова, МАКС Пресс Москва, 2016 – 72 с.

23. Розов А.С., Зюбин В.Е., Нефедов Д.В., Программирование встраиваемых микроконтроллерных систем на основе гиперпроцессов //Вести, НГУ, Серия: Информационные технологии, 2017, Т.15, №4, с. 64-73

24. Симдянов И. В., Самоучитель Ruby, издательство БХВ-Петербург, 2020 – 656 с.

25. Соркин Э., Слишком большие, чтобы рухнуть, издательство Corpus, 2012 – 576 с.

26. Тарасов В.Б., От многоагентных систем к интеллектуальным организациям, М.: Едиториал УРСС, 2002 - 352 с.

27. Трасковский А. В. Устройство, модернизация, ремонт IBM PC. — СПб.: БХВ-Петербург, 2004. — 608 с.

28. Федотова Д. Э., Семенов Ю. Д., Чижик К. Н., Case-технологии. Практикум, Издательство: Горячая Линия – Телеком, 2005 - 160 c.

29. Холден С., Рейвенскрофт А., Мартелли А., Python. Справочник. Полное описание языка, издательство Диалектика, 2018 – 896 c.

30. Хоффман, Дэвид. «Мёртвая рука». Неизвестная история холодной войны и её опасное наследие. — М.: Астрель, 2011 -736 с.

31. Чанышев О.Г. Основные элементы языка программирования Icon: Учебное пособие. - Омск: Изд-во ОмГУ, 2004 - 55 с.

32. Lindholm T., Yellin F., Bracha B., Java virtual machine specification, java se 8 edition, Published Pearson Addison Wesley Prof, 2014 – 600 p.

33. Shoham Yoav. Agent Oriented Programming: Technical Report STAN-CS-90-1335. — Computer Science Department, Stanford University, 1990.

34. Stakem P., Cubesat Operations: How to fly a Cubesat, издательство: Independently published, 2017 – 98 с.

35. Zuse K. «Der Plankalkül». Gesellschaft für Mathematik und Datenverarbeitung. Nr. 63, BMBW - GMD - 63, 1972 - 63 p.

36. http://kmpu.ru/theory/index.html#Chapter_1

37. https://habr.com/ru/post/20425/

38. https://hi-news.ru/auto/podtverzhdeno-po-vine-avtopilota-tesla-pogiblo-uzhe-chetyre-cheloveka.html

39. https://proglib.io/p/oop-fail

40. https://ru.wikipedia.org/wiki/Therac-25

41. https://ru.wikipedia.org/wiki/Turbo_Pascal

42.https://ru.wikipedia.org/wiki/Случаи_ложного_срабатывания_систем_предупреждения_о_ракетном_нападении

43. https://tass.ru/info/2123307

44. https://www.kommersant.ru/doc/1530174

45. https://www.popmech.ru/technologies/46176-top-6-katastrof-proizoshedshikh-po-vine-programmnogo-obespecheniya/

46. https://www.popmech.ru/technologies/46176-top-6-katastrof-proizoshedshikh-po-vine-programmnogo-obespecheniya/

47. https://www.pwc.com/gx/en/services/audit-assurance/publications/global-top-100-companies.html

48. https://www.sandc.com

ПРИЛОЖЕНИЕ 1

Код на языке С++ для считывания показаний датчика температуры DS18S20

/*

модуль работы с датчиком температуры TMP36

Автор кода: Жердин Дмитрий Анатольевич, 2019 (с), zherdin@mail.ru

модуль является частью проекта: Сервер устройств на основе Ардуино

*/

// создание аналогового порта ввода для датчика температуры TMP36 (36GZ), параметры датчика:

// -40 до 150°С, ±2°C , при температуре 25°C: ±1°C

// линейность: ±0.5°C

// разрешение: 10.0 mV/°C

// напряжение на выходе при 25°C: 750мВ

// потребление тока не более 0,5 мкА

// корпус TO-92, питание 2.7 – 5.5 В

// пины: 1-питание, 2-выходное напряжение температуры, 3-земля

// при питании от 5В используется следующая формула для преобразования 10-битных аналоговых значений в температуру:

// 1. вычисляем напряжение на пине в милливольтах = (значения с аналогового пина АЦП) * (5000/1024)

// 2. вычисляем температуру в цельсиях = [(напряжение в милливольтах на пине) - 500] / 10

// параметры URL должны выглядеть так: ?PORT=TMP36_SENSOR, PIN= [14]

// ответ клиенту: если PIN задан верно - значение температуры от -40 до 150 С, иначе PIN_NUMBER_ERROR

String MakePort_TMP36_SENSOR(String RequestURL) {

if (DEBUG) Serial.println("!MakePort_TMP36_SENSOR(String RequestURL)"); // выводим данные в монитор порта

if (DEBUG) Serial.println("!RequestURL: "+RequestURL); // выводим данные в монитор порта

// получаем значение параметра "PIN" в строковом формате

String PIN=getValueURLparameter(RequestURL,"PIN");

// проверяем был ли найден параметр PIN

if (PIN=="") return String("PIN_NUMBER_NOT_FOUND_ERROR"); // параметр не найден, возвращаем ошибку

// параметр PIN найден, преобразуем его в числовой формат

int PIN_number=PIN.toInt();

// проверяем лежит ли номер ПИНа в разрешенном диапазоне (использование псевдонимов вида А1, А2..., запрещено!).

// на МЕГА аналоговые пины имеют номера 54-69

if (PIN_number<54 || PIN_number>69) return String("PIN_NUMBER_ERROR"); // неверный номер пина, возвращаем ошибку

// параметры заданы верно!

if (DEBUG) Serial.println("!================= PARAMETERS IS OK ====================");

if (DEBUG) Serial.println("!PIN_number: "+String(PIN_number)); // выводим данные в монитор порта

// переключаем физический аналоговый порт контроллера в режим ввода

// подтягивать порт к ПИТАНИЮ через встроенный PULLUP-резистор не надо т.к. он будет мешать измерениям (встроенный резистор подтягивает только к питанию)

// однако если порт уже был ранее подтянут к питанияю через встроенный резистор его нужно оттянуть.

// в прежних версиях ардуины использовались две команды

pinMode(PIN_number, INPUT); // переводим порт в режим ввода

digitalWrite(PIN_number, LOW); // отключаем подтягивающий резистор

// 1. вычисляем напряжение на пине в миливольтах = (значения с аналогового пина АЦП) * (5000/1024)

// 2. вычисляем температуру в цельсиях = [(напряжение в милливольтах на пине) - 500] / 10

// читаем состояние физического аналогового порта контроллера, к которому подключен датчик температуры

// переменная для чтения аналогового порта (вещественная т.к. будет делиться для подсчета среднего значения)

double AnalogValue=0;

// цикл чтения 100 показаний датчика температуры для вычисления среднего значения

for (int i=1; i<=100; i++) AnalogValue+=analogRead(PIN_number);

// вычисляем среднее значение

AnalogValue/=100;

if (DEBUG) Serial.println("!AnalogValue: "+String(AnalogValue)); // выводим данные в монитор порта

// преобразуем показания аналогового порта в напряжение (для контроллера с аналоговым выходом 3.3v используется значение 3.3, для 5v - 5.0)

double MilliVoltage = AnalogValue * (5000.0 / 1024.0);

if (DEBUG) Serial.println("!MilliVoltage : "+String(MilliVoltage )); // выводим данные в монитор порта

// вычисляем температуру в градусах Цельсия

// исходя из того, что 10 мВ равны 1 градусу (со смещением 500 мВ т.к. первые 500мВ - это отрицательная температура)

double TemperatureC = (MilliVoltage - 500.0) / 10.0 ;

if (DEBUG) Serial.println("!TemperatureC: "+String(TemperatureC)); // выводим данные в монитор порта

// возвращаем значение температуры по Цельсию в строковом формате

return String(TemperatureC);

} //String MakePort_TMP36_SENSOR(String RequestURL)

ПРИЛОЖЕНИЕ 2

Финансовые потери от простоев в работе на 2015 год (США)

по данным www.sandc.com

Потери от простоев в работе от отключения электроэнергии