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

Основные понятия объектно-ориентированного программирования (Модификация)

Содержание:

Введение

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

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

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

Многие авторы в своих работах затрагивали концепцию объектно-ориентированного программирования, существует огромное количество книг и учебников, как для новичков, так и для профессионалов. Многообразие может слегка пугать, так что необходимо выделить несколько основных фамилий, в чьих научных трудах наиболее полно и понятно была раскрыта рассматриваемая тема - сама концепция объектно-ориентированного программирования и её применение в различных языках. Разумеется, далеко не каждый язык программирования подходит для применения объектно-ориентированного подхода, можно выделить такие языки как C#, C++, Java, Delphi, Object Pascal, Python, JavaScript, Ruby, PHP и другие в качестве тех, которые основаны на принципах объектно-ориентированного программирования.

Из наиболее известных авторов следует упомянуть Тимоти Бадда и его книгу «Объектно-ориентированное программирование», которое рассказывает про основные принципы и их применение на практике, а также Айру Пола, написавшего «Объектно-ориентированное программирование на С++», которая, строго говоря, не является ни учебником по С++, ни учебником по ООП, но показывающая, как именно следует применять парадигму объектно-ориентированного программирования при написании программ на языке С++.

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

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

Постановка основных задач:

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

1. Теоретические сведения об объекте исследования (ООП)

1.1 Основные понятия

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

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

Основные модели программирования:

  • Императивное программирование;
  • Декларативное программирование;
  • Структурное программирование;
  • Функциональное программирование;
  • Логическое программирование;
  • Объектно-ориентированное программирование.

Абстрактный тип данных - это тип данных, который предоставляет для работы с элементами этого типа определённый набор функций, а также возможность создавать элементы этого типа при помощи специальных функций. Вся внутренняя структура такого типа спрятана от разработчика программного обеспечения — в этом и заключается суть абстракции. Абстрактный тип данных определяет набор функций, независимых от конкретной реализации типа, для оперирования его значениями. Конкретные реализации АТД называются структурами данных. [7]

1.2 Объектно-ориентированное программирование

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

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

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

Объектно-ориентированное программирование напрямую сфокусировано на данных, причем данные тесно связаны с поведением, вместе же данные и поведение представляют собой единую связанную систему - класс. Каждый экземпляр отдельно взятого класса называется объект и является основой всей парадигмы объектно-ориентированного программирования. [4] [21]

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

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

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

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

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

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

рис.1.1.

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

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

Инкапсуляция является свойством языка программирование, главным назначением которого является сокрытие внутренней информации от пользователя, позволяет пользоваться программным компонентом без знания его реализации. Для взаимодействия пользователя и объекта используется спецификация - интерфейс объекта, который включает в себе все публичные методы и данные. Пользователь может взаимодействовать с объектом только через этот интерфейс. Реализуется с помощью ключевого слова: public. Все данные и методы, которые отмечены как публичные, могут быть вызваны и изменены вне класса. Закрытые же методы остаются закрытыми, реализуются с помощью ключевых слов: private, protected, internal и недоступны для вызова или изменения извне. Очень важно правильно определять, какие данные и методы следует оставлять открытыми для пользователя, а какие закрытыми. Расценивая целесообразность применения сокрытия реализации от пользователя, следует обратить внимание на следующие вопросы: нужна ли локализация изменений при их необходимости, насколько изменения и их последствия являются прогнозируемыми, то есть, как нужно изменить код, чтобы добиться требуемого изменения функциональности.

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

Полиморфизм - возможность объектов с одинаковой спецификацией иметь различную реализацию. [8]

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

Кратко смысл полиморфизма можно выразить фразой: «Один интерфейс, множество реализаций».

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

• внешняя общность проявляется как одинаковый набор методов с одинаковыми именами и сигнатурами (именем методов и типами аргументов, и их количеством);

• внутренняя общность — одинаковая функциональность методов. Её можно описать интуитивно или выразить в виде строгих законов, правил, которым должны подчиняться методы. Возможность приписывать разную функциональность одному методу (функции, операции) называется перегрузкой метода (перегрузкой функций, перегрузкой операций). [8]

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

Понятие объектно-ориентированного программирования включает в себе довольно объемный набор концепций, вот некоторые из них:

- Моделирование действия из реального мира;

- Наличие типов данных, определяемых пользователем;

- Сокрытие деталей реализации;

- Возможность многократного использования кода благодаря наследованию;

- Интерпретация вызовов функций на этапе их выполнения. [4]

1.3 Объектно-ориентированные языки программирования

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

Simula (1967), как правило, считается первым языком с первичными особенностями объектно-ориентированного языка. Он был создан для проектирования программ моделирования, в которых то, что стали называть «объекты», было самым важным представлением информации. Smalltalk (1972 по 1980), возможно, является каноническим примером, а также тем, на основании которого была разработана большая часть теории объектно-ориентированного программирования. Что касается степени ориентации объекта, могут быть выделены следующие подтипы:

  • Чисто объектно-ориентированные языки, все в них обрабатывается последовательно в качестве объекта, начиная от примитивов, таких как символы и знаки препинания, вплоть до целых классов, прототипов, блоков, модулей и т.д. Они были разработаны специально для облегчения применения методов объектно-ориентированного программирования. Примеры: Eiffel, Emerald, Obix, Ruby, Scala, Smalltalk;
  • Языки, которые предназначены главным образом для объектно-ориентированного программирования, но с некоторыми процедурными элементами. Примеры: Delphi / Object Pascal, C++, Java, C #, VB.NET, Python;
  • Языки, которые исторически являлись процедурными языками, но были расширены некоторыми объектно-ориентированными особенностями. Примеры: Паскаль, Visual Basic (производный от BASIC), MATLAB, Fortran, Perl, COBOL 2002, PHP, ABAP, Ада 95; [9]
  • Языки с поддержкой абстрактного типа данных, но не всех других особенностей объектно-ориентированного программирования. Примеры: Modula-2, Pliant, CLU. [9]

2. Теоретические сведения о предмете исследования (этапы ООП)

2.1 Основные этапы объектно-ориентированного программирования

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

При разработке программного обеспечения с использованием объектно-ориентированного подхода проходят следующие этапы:

  • Анализ;
  • Проектирование;
  • Эволюция;
  • Модификация.

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

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

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

Анализ

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

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

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

Итак, этап анализа разбивается на следующие подпункты, а именно:

  • Анализ предметной области задачи. Во время анализа собственно предметной области задачи выделяются её сущности и определяются исходные требования к функциональности программного обеспечения, кроме того определяются некие границы объекта;
  • Объектная декомпозиция разрабатываемой системы. При объектной декомпозиции система разбивается на объекты или компоненты, которые взаимодействуют друг с другом, обмениваясь сообщениями. Сообщения описывают или представляют собой некоторые события;
  • Описание абстракций. Определяются важнейшие особенности поведения объектов;
  • Структурная схема. На структурной схеме должны быть отображены все объекты и те сообщения, которыми они обмениваются между собой.

Например, необходимо разработать программный продукт «Телефонная книга». На первом этапе определяются основные требования к данному приложению: оно поддерживать хранение до 100 записей, их добавление и удаление. Основными компонентами приложения будут запись телефонной книги и менеджер функций.

Проектирование

На этапе проектирования происходит определение архитектуры, компонентов, интерфейсов и других характеристик системы или ее компонентов. [9]

Можно выделить такие типы проектирования:

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

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

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

На данном этапе (продолжение примера из предыдущего раздела) для некоего разрабатываемого приложения «Телефонная книга» строится структура классов. Например, понятно, что для корректной работы телефонной книги в ней должен быть класс «Запись» с полями «Имя», «Фамилия», «Телефонный номер», а также класс «Менеджер функций» с методами «Добавление», «Удаление», «Редактирование». Во время этапа физического проектирования также выбирается способ хранения информации, например, текстовый файл или база данных.

Эволюция

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

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

http://85.142.23.53/packages/1C/16F0975D-4AEF-AF54-A125-BAF50F2F2BE6/1.0.12.20/unpacked/media/img/214141/214146.jpg

рис. 2.1.

После тестирования и отладки, а также, возможно, уточнения каких-то требований, к данной системе подключаются другие группы классов, допустим, класс «Менеджер функций» телефонной книги и реализуются оставшиеся методы. По мере подключения всё новых классов прототип точно также тестируется и отлаживается. На рисунке выше показана блок-схема алгоритма, объясняющая, как именно происходит этот процесс. [5]

Поэтапная реализация программного продукта очень упрощает его тестирование и отладку.

Если говорить про «Телефонную книгу» (пример, использующийся ранее), то на этапе эволюции выполняется её программная реализация.

Модификация

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

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

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

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

На четвертом этапе для разрабатываемого приложения «Телефонная книга» добавляется новая функциональная возможность – функция сортировки записей.

3. Практическая часть

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

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

Средой разработки программного обеспечения была выбрана Microsoft Visual Studio 2012, а языком программирования - С++, он современный и достаточно удобный, поддерживает парадигму объектно-ориентированного программирования, обеспечивает модульность, разрешение компиляцию, обработку исключений, абстракцию данных, объявления типов (классов) объектов, виртуальные функции. [4]

Постановка задачи:

Необходимо определить наличие гамильтонова цикла в ориентированном графе.

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

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

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

Гамильтонов цикл - разновидность гамильтонова пути, в котором начальная и конечная точки совпадают. [10]

Гамильтонов путь, или цепь - такой путь (цепь), который содержит каждую вершину графа только один раз. [10]

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

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

Следовательно, после того, как все эти сведения найдены и обработаны, можно определиться с теми сущностями, которые потребуются.

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

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

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

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

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

Структура будет иметь такой вид:

struct matrix{ // структура для матрицы

int size; // порядок матрицы

int *_array; // целочисленный массив

};

А класс для графа следующий:

class Graph { // рабочий класс

private:

int arr_size; // порядок матрицы

int *arr; // целочисленный массив

bool is_cycle; // найден ли цикл

int *poseshenie; // счетчик посещений вершины

bool *mark ; // массив меток

public:

Graph(matrix *g); // конструктор

Graph(Graph &T); // конструктор для копии

void Graph::DFS(int v); // функция обхода

void Set(matrix*g); // связывает объект задачи с графом g и выполняет решение задачи для графа g

void Restart(); // повторно выполняет решение задачи для графа g

bool Result(); // результат

~Graph(); // деструктор

};

Объявления классов и структур содержится в заголовочном файле graph.h, а вот их определения - в файле graph.cpp.

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

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

Graph::Graph(matrix *g){ // конструктор с параметром-матрицей

this->arr_size = g->size;

poseshenie = new int [arr_size];

mark = new bool [arr_size];

if (g->size>0){

arr = new int[g->size*g->size];

memcpy(arr,g->_array,sizeof(int)*(g->size)*(g->size));

}

else arr=NULL;

this->Restart();

}

Graph::Graph(Graph &T){ // конструктор, создающий копию объекта

this->arr_size = T.arr_size;

poseshenie = new int [arr_size];

mark = new bool [arr_size];

if (this->arr_size>0){

arr = new int[T.arr_size*T.arr_size];

memcpy(arr,T.arr,sizeof(int)*(T.arr_size)*(T.arr_size));

}

else arr= NULL;

this->Restart();

}

Graph::~Graph(){ // деструктор

arr_size =0;

delete [] arr;

delete [] poseshenie;

delete [] mark;

}

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

1. Функция обхода графа.

void Graph::DFS(int v){

int i;

bool tmp=true;

mark[v]=true;

poseshenie[v]++;

///тут проверка на обход единожды

for (i=0; i<arr_size; i++)

if ((!mark[i])||(poseshenie[i]!=1)) {

tmp=false;

break;

}

if (tmp) is_cycle = true;

///

for (i=0; i<arr_size; i++){

if (arr[v*arr_size+i]==1)

if(mark[i]==0){

DFS(i);

poseshenie[v]++;

}

}

}

2. Функция, которая связывает объект задачи с графом g и выполняет решение задачи для графа g.

void Graph::Set(matrix*g){

this->arr_size = g->size;

if (g->size>0){

arr = new int[g->size*g->size];

memcpy(arr,g->_array,sizeof(int)*(g->size)*(g->size));

}

else arr=NULL;

this->Restart();

}

3. Функция, которая повторно выполняет решение задачи для графа g.


void Graph::Restart(){

is_cycle = false;

if (arr_size<1) return;

int i, v;

for (v=0; v<arr_size; v++){

for (i=0; i<arr_size; i++){

poseshenie[i]=0;

mark[i]=false;

}

DFS(v);

}

}

И функция, возвращающая результат:

bool Graph::Result(){

return is_cycle;

}

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

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

/* случайная генерация матрицы */

void rnd_matrix(int &size,int maxsize, int ** matr){

if (maxsize<2) return;

srand(int(time(NULL)));

size = 2+ rand()%(maxsize-1);

*matr = new int [sizeof(int)*size*size];

for (int i=0;i<size*size;i++)

if (rand()<16000)

(*matr)[i]=rand()%2;

else (*matr)[i]=0;

}

/* вывод матрицы на экран */

void print_matrix(int size,int *matr){

for (int i =0;i<size;i++){

for (int j=0;j<size;j++)

printf("%2d",matr[i*size+j]);

printf("\n");

}

}

В итоге главная функция программы принимает следующий вид:

int main()

{

matrix a;

rnd_matrix(a.size,10,&a._array);

printf("Sourse 1 graph-matrix-\n");

print_matrix(a.size,a._array);

Graph g(&a);

if (g.Result()) printf("True\n");

else printf("False\n");

g.Set(&a); //проверка процедуры сет

Graph g1(g); //конструктор копирования

int *p = new int [4] ;

matrix b = {2,p}; //тестовый пример матрицы 2х2

b._array[0]= 0; b._array[1]= 1;

b._array[2]= 0; b._array[3]= 0;

printf("Sourse 2 graph-matrix-\n");

print_matrix(2,b._array);

Graph g2(&b);

if (g2.Result()) printf("True\n");

else printf("False\n");

p = new int [9];

matrix c = {3,p}; //тестовый пример матрицы 3x3

for (int i = 0;i<9;i++) c._array[i]=0;

c._array[1]= 1; c._array[5]= 1;

printf("Sourse 3 graph-matrix-\n");

print_matrix(3,c._array);

Graph g3(&b);

if (g3.Result()) printf("True\n");

else printf("False\n");

_getch();

return 0;

}

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

На рисунках ниже (3.1 и 3.2) показан результат работы программы. Здесь матрица графа сгенерирована случайно (3 раза) и показаны результаты расчета для каждого из них.

рис.3.1.

рис.3.2.

Заключение

В данной курсовой работе была рассмотрена парадигма объектно-ориентированного программирования, а также этапы объектно-ориентированного программирования.

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

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

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

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

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

Целями объектно-ориентированного программирования являются:

  • более глубокое понимание;
  • простота обслуживания;
  • простота эволюции.

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

Список литературы

1. Е. А. Роганов - «Основы информатики и программирования» - Москва, 2001 - 299 с.

2. Тимоти Бадд - «Объектно-ориентированное программирование».

3. Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес - «Приёмы объектно-ориентированного программирования. Паттерны программирования» - Санкт-Петербург, 2001 - 352 с.

4. А. Пол - «Объектно-ориентированное программирование на С++».

5. С.В. Акимов - «Введение в Интернет-технологии (учебник)»

6. М.В. Кузнецов - «Объектно-ориентированное программирование на PHP» - Москва, 2012

7. В. А. Лапшин - «Абстрактные типы данных в программировании»

8. https://github.com/Mikhail-Ivanov/Programming-manual/

9. Г.С. Иванова, Т.Н. Ничушкина, Е.К. Пугачев - «Объектно-ориентированное программирование» - Москва, 2001 - 320 с.

10. Ф. Харари - «Теория графов» - Москва, 1973 - 300 с.

11. И. Грэхем - «Объектно-ориентированные методы. Принципы и практика» - Москва, 2004 - 880 с.

12. А. Синтес - «Освой самостоятельно объектно-ориентированное программирование за 21 день» - Москва, 2002 - 672 с.

13. Matt Weisfeld - «The Object-Oriented Thought Process» - Addison-Wesley Professional, 2013 — 336 с.

14. Кирютенко Ю.А., Савельев В.А. - Объектно-ориентированное программирование. Язык Smalltalk - Москва, 2006 - 328 с.

15. Дж. Мараско - «IT-проекты. Фронтовые очерки» - Москва, 2010 - 379 с.

16. Р. Лафоре - «Объектно-ориентированное программирование в С++» -Питер, 2004 - 928 с.

17. Т.А. Павловская, Ю. А. Щупак - «C++. Объектно-ориентированное программирование: Практикум» - Питер, 2006 - 265 с.

18. В. В. Лаптев, А.В. Морозов, А.В. Бокова - «С++. Объектно-ориентированное программирование. Задачи и упражнения» - Питер, 2007 - 288 с.

19. В.М. Бондарев - «Программирование на С++ (2 изд.)» - Харьков, 2005 - 284 с.

20. В.И. Медведев - «Особенности объектно-ориентированного программирования на C++/CLI, C# и Java» - Казань, 2010 - 320 с.

Язык: Русский

21. Б. Страуструп - «Дизайн и эволюция языка C++. Объектно-ориентированный язык программирования» - Москва, 2000 - 448 с.