Как писать модульные программы

Содержание

В дополнение к вебкасту Prism: Composite Application Guidance for WPF and Silverlight хотелось бы сделать еще несколько умозаключений. “Призма” на данный момент очень распространенный подход к разработке программных продуктов. За рубежом если вы найдете какую-нибудь работу на WPF или Silverlight первый вопрос, который вам зададут “А знаете ли вы призму?”. Чтобы узнать ее можете посмотреть первые 20 минут скринкаста, где я описываю основные моменты данного подхода. Узнать призму – это безусловно хорошо, но еще лучше знать зачем она нужна. Постараюсь привести пару простых примеров модульных приложений.

Модульные приложения

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

Да и руководитель проекта раскидывает обычно задачи разработчикам в зависимости от функциональности. Например, если мы пишем CRM: то задачи можно разбить так – “ты занимайся информацией о клиентах, а ты занимайся расписанием (задачи, встречи и т.п.)”. Как раз это и можно разбить на настоящие модули, а именно на отдельные библиотеки.

3 Простейший способ создания юнит тестов на C++

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

Что же даст нам четкое разбиение на модули? В случае Silverlight приложения – если наше приложение имеет разграничения прав доступа к функционалу, то в зависимости от прав пользователя подгружать разные модули: будет небольшой выигрыш в трафике.

В этом же и в любом другом случае, если обеспечена достаточная независимость модулей друг от друга – возможность продавать разные компоновки нашего программного продукта. А как обеспечивать эту самую независимость? С этой задачей помогает иногда справиться Dependency Injection (DI). Почему иногда? Небольшие костыли все же нужно будет иногда подставлять.

Инъекция представлений

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

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

sample form

Напрашивается такой выход, у нас есть Region “Contact Persons List” и нам необходима инъекция в этот регион определенной формы в зависимости от условия. Решаем задачу так: в модуле компаний создаем интерфейс IContactPersonsView – представление списка контактов, у которого есть, предположим, метод инициализации с передачей идентификатора компании.

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

Теперь нам остается найти механизм, который сможет подставить в регион “Contact Persons List” необходимое представление. Тут нам поможет DI контейнер. Модули контактных персон при загрузке будут регистрировать соответствия своего типа к интерфейсу IContactPersonsView. А модуль компаний при отображении этого окна будет находить зарегистрированный тип к интерфейсу IContactPersonsView, создавать новый объект этого типа и делать инъекцию в необходимый регион. Еще нужно сделать зависимость, чтобы модуль компании загружался именно после модуля персон, чтобы он уже мог получить соответствие, какое представление зарегистрировано на его регион.

Работа с событиями

Есть другой пример, теперь у нас представление выглядит так:

sample form

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

Читайте также:
Исследовательская программа лакатоса кратко

В случае модульного приложения у нас нет понимания, на какой форме какое наше представление (контрол) будет располагаться, а так же нет должного представления, какой именно контрол будет там располагаться. Здесь нам бы помог некий механизм публикации событий. То есть контрол Companies List при выборе определенной компании публикует через данный механизм информацию об этом событии (каким-то образом его идентифицируя), а контрол Details List (либо даже это может быть набор контролов) просто подписывается через данный механизм на события этого типа. Самый простой способ реализация данного подхода – сделать статический event в каком-нибудь классе, к которому есть доступ как из Companies List, так и из Details List. В CompositeWPF для этого предоставлен Event Aggregator.

Итог

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

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

See Also

  • Вебкаст — Prism: Composite Application Guidance for WPF and Silverlight
  • WPF 4.0. Что нового? Часть 5.
  • WPF 4.0. Что нового? Часть 4.
  • Минимум кода для отображения окна на WPF
  • Паттерны: MVC, MVP и MVVM

Found a misprint? Feel free to send a Pull Request or open an issue.

Have a question about the post? You tried, something does not work? GitHub discussions.

Источник: www.outcoldman.com

Модульное программирование

Машинно-ориентированное программирование появилось одновременно с созданием электронных вычислительных машин. Сначала это были программы в машинных кодах, затем появился язык программирования Assembler (Автокод), который немного «очеловечил» написание программы в машинном коде. Этот стиль программирования предполагает доскональное знание возможностей конкретной архитектуры ЭВМ и операционной системы и используется до сих пор тогда, когда другие стили бессильны, или нужно получить максимальное быстродействие в рамках той или иной операционной системы с использованием архитектуры данной ЭВМ.

Введение ……………………………………. …………………………. 3
1. Теоретические аспекты модульного программирования ………………..….6
1.1 Цель модульного программирования ………………………………. …..6
1.2 Основные характеристики программного модуля ……………………..14
1.3 Проектирование модуля ………………………………………………. 21
1.3.1 Функциональная декомпозиция ………………………………………. 22
1.3.2 Минимизации количества передаваемых параметров ………………….24
1.3.3 Минимизации количества необходимых вызовов …………..…….25
1.4 Методы разработки структуры модульной программы . …………. ….27
1.5 Контроль структуры модульной программы . …………………..…34
2. Практическая часть. Код программы «Блокиратор рабочего стола» …….35
Заключение ……………………………………………………………….38
Список исползуемых источников …. ………………………..………. 39

Содержимое работы — 1 файл

Челябинский юридический колледж

Кафедра информатики и вычислительной техники

по дисциплине «технические разработки программных продуктов»

Студент гр. ПО 1-3-09

программное обеспечение ВТ и АС ___________________ Р.С. Терентьев

Преподаватель ___________________ А.А. Гришаев

Рецензент ____________________ А.А. Гришаев «__» _________________2012

1. Теоретические аспекты модульного программирования ………………..….6

1.1 Цель модульного программирования ………………………………. …..6

1.2 Основные характеристики программного модуля ……………………..14

1.3 Проектирование модуля ………………………………………………. 21

1.3.1 Функциональная декомпозиция ………………………………………. 22

1.3.2 Минимизации количества передаваемых параметров ………………….24

1.3.3 Минимизации количества необходимых вызовов …………..…….25

1.4 Методы разработки структуры модульной программы . …………. ….27

1.5 Контроль структуры модульной программы . …………………..…34

2. Практическая часть. Код программы «Блокиратор рабочего стола» …….35

Список исползуемых источников …. ………………………..………. 39

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

Машинно-ориентированное программирование появилось одновременно с созданием электронных вычислительных машин. Сначала это были программы в машинных кодах, затем появился язык программирования Assembler (Автокод), который немного «очеловечил» написание программы в машинном коде. Этот стиль программирования предполагает доскональное знание возможностей конкретной архитектуры ЭВМ и операционной системы и используется до сих пор тогда, когда другие стили бессильны, или нужно получить максимальное быстродействие в рамках той или иной операционной системы с использованием архитектуры данной ЭВМ.

Процедурное программирование. Основная идея этого стиля – алгоритмизация процесса решения задачи и выбор наилучшего алгоритма (по расходу памяти или по быстродействию). Реализация этой идеи началась с 1957 года с появлением алгоритмических языков Fortran и затем Algol-60, когда все большее и большие число специалистов занялось решением достаточно сложных инженерных и научных задач.

И нужен был стиль программирования максимально близкий к человеческому (математическому) стилю. При этом знание тонкостей архитектуры ЭВМ не требовалось. Программа на алгоритмическом языке (при наличии соответствующих трансляторов) должна была в идеале работать на ЭВМ любой архитектуры. Но это были программы прикладные. Разработку же системных программ (самих трансляторов, систем ввода-вывода) по-прежнему надо было делать на Ассемблере.

Структурное программирование. Здесь основная идея прекрасно выражена Н. Виртом в его книге «Алгоритмы + структуры данных = программы». Это был ответ на кризис в области программирования, начавшийся в середине 60-х годив, когда объем исходного программного кода перешел рубеж в 1000 строк.

Читайте также:
Список лучших программ для Андроид

В 1971 году появился алгоритмический язык Pascal и немного позже, в 1972 году, язык С. Алгоритмические языки стали более мощными, более «интеллектуальными», на них уже можно было писать элементы трансляторов (компиляторов) и драйверов (подпрограмм обработки ввода-вывода). Компиляторы с языков С и Fortran выдают, например, по требованию программиста и листинг программы на Ассемблере. Знающий Ассемблер программист может его проанализировать, что-то подправить и перекомпилировать, но уже на Ассемблере. В этом случае можно достаточно быстро и эффективно получать системные программы.

Модульное программирование. Здесь основная идея заключалась в том, чтобы «спрятать» данные и процедуры внутри независимых программных единиц — модулей. Эту идею впервые реализовал Н. Вирт в алгоритмическом языке Modula (1975-1979 годы), а затем «подхватили» и остальные, распространенные в то время языки программирования. Например, известные системы программирования Turbo Pascal и Turbo С.

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

Объектно-ориентированное программирование. С середины 80-х годов объем исходного программного кода перешел рубеж в 100 000 строк. Нужно было сделать не случайное объединение данных и алгоритмов их обработки в единое целое, а — смысловое. То есть необходимо было создать модульное программирование нового уровня, когда основной акцент делается на смысловую связь структур данных и алгоритмов их обработки. Сейчас практически все основные языки программирования (их более 100, в том числе такие распространенные, как Object Pascal, C++, Smalltalk) базируются на этой идее, а предком их является язык Simula, созданный еще в 1960 году.

Обобщенные технологии разработки приложений. Идеология объектно-ориентированного программирования породила CASE-технологии разработки и сборки программ на основе уже известных программных моделей, содержащих интерфейсы и прототипы (шаблоны — template) данных: COM (Component Object Model), STL (Standard Template Library), ATL (Active Template Library). Все эти новшества поддерживают визуальные среды разработки, например, такие известные, как Visual C++, Borland C++ Builder, Borland Delphi.

Теперь подробно рассмотрим технологию модульного программирования.

1. Теоретические аспекты модульного программирования

Цель модульного программирования

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

Модуль – автономно компилируемая программная единица.

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

Цели модульного программирования:

— упрощение разработки и реализации программ

— улучшение «читаемости» программ

— упрощение настройки и модификации программ

— упрощение работы с данными, имеющими сложную структуру

— избежание чрезмерной детализации алгоритмов

— более выгодное размещение программ в памяти ЭВМ

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

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

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

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

Практика показала, что чем выше степень независимости модулей, тем:

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

— меньше вероятность появления новых ошибок при исправлении старых или внесении изменений в программу

— проще организовать разработку ПО группой программистов и легче его сопровождать.

Не всякий программный модуль способствует упрощению программы. Для оценки приемлемости выделенного модуля используются некоторые критерии.

Хольт предложил следующие общие критерии:

— хороший модуль снаружи проще, чем внутри

— хороший модуль проще использовать, чем построить.

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

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

Читайте также:
Пример программы на sfc

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

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

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

— всегда следует использовать рутинный модуль, если это не приводит к не рекомендуемым сцеплениям модулей

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

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

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

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

Сцепление, или связанность, модулей – мера их взаимозависимости.

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

Типы сцепления модулей:

— по данным: модули взаимодействуют через передачу параметров; каждый параметр – элементарный информационный объект. Это наиболее предпочтительный тип связанности модулей.

Источник: www.turboreferat.ru

презентация на тему модульное программирование ТИМП. Модульное программирование. Модульное программирование и его особенности Модульное программирование

Единственный в мире Музей Смайликов

Самая яркая достопримечательность Крыма

Скачать 0.72 Mb.

Модульное программирование и его особенности

Модульное программирование

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

Основные и вспомогательные модули

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

Свойства модуля

  • Один вход и один выход. На входе программный модуль получает определенный набор исходных данных, выполняет их обработку и возвращает один набор выходных данных;
  • Функциональная завершенность. Модуль выполняет набор определенных операций для реализации каждой отдельной функции, достаточных для завершения начатой обработки данных;
  • Логическая независимость. Результат работы данного фрагмента программы не зависит от работы других модулей;
  • Слабые информационные связи с другими программными модулями. Обмен информации между отдельными модулями должен быть минимален;
  • Размер и сложность программного элемента в разумных рамках.

Основные характеристики программного модуля

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

Методы разработки при модульном программировании

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

Пример создания модуля

function Summ (Slag1, Slag2 : real) : real;

Summ := Slag1 + Slag2;

Метод восходящей разработки

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

Недостатки метода:

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

Метод нисходящей разработки

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

Достоинства метода: возможность нисходящего тестирования и комплексной отладки.

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

Структура модуля

Структура модуля

«Интерфейс» — общедоступная информация: объявления типов данных,

Объявления процедур и функций.

«Реализация» – внутренняя информация модуля: код процедур и функции, внутренние данные.

Подпрограммы (функции)

Подпрограммы также являются свойством построения модульных программ. Не всякая подпрограмма является модулем. Модуль должен удовлетворять характеристикам и свойствам модулей.

Пример использования подпрограмм

Int main(int argc, char* argv[])

puts (“input x, eps”);

printf (“SUMMA Ryada. = %8.7n”, sumr(x, eps));

Источник: topuch.com

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru