Опубликован: 23.10.2005 | Доступ: свободный | Студентов: 3868 / 144 | Оценка: 4.44 / 4.19 | Длительность: 33:04:00
Специальности: Программист
Лекция 9:

Объектно-ориентированный анализ

Программирование телевизионного вещания

Рассмотрим конкретное применение ОО-концепций в интересах чистого моделирования.

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

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

Графики вещания

Сосредоточимся на 24-часовом графике вещания. Его представляет класс (абстракция данных) SCHEDULE. График содержит последовательность отдельных программных сегментов:

class SCHEDULE feature
    segments: LIST [SEGMENT]
end

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

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

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

indexing
    description: "24-часовой график ТВ вещания"
deferred class SCHEDULE feature
    segments: LIST [SEGMENT] is
            -- Последовательность сегментов
        deferred
        end
    air_time: DATE is
            -- Дата вещания
        deferred
        end
    set_air_time (t: DATE) is
            -- Установка даты вещания
        require
            t.in_future
        deferred
        ensure
            air_time = t
        end
    print is
            -- Вывод графика на печать
        deferred
        end
end

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

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

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

Сегменты

Прежде чем продолжать уточнение и расширение SCHEDULE, необходимо обратиться к понятию SEGMENT. Можно начать со следующего описания:

indexing
    description: "Отдельные сегменты графика вещания"
deferred class SEGMENT feature
    schedule: SCHEDULE is deferred end
            -- График, содержащий данный сегмент
    index: INTEGER is deferred end
            -- Положение сегмента в графике
    starting_time, ending_time: INTEGER is deferred end
            -- Время начала и завершения
    next: SEGMENT is deferred end
            -- Следующий сегмент, если он существует
    sponsor: COMPANY is deferred end
            -- Основной спонсор
    rating: INTEGER is deferred end
            -- Рейтинг сегмента (допустимость просмотра детьми и т.д.)
    ... Опущены команды change_next, set_sponsor, set_rating и др. ...
    Minimum_duration: INTEGER is 30
            -- Минимальная длительность сегмента в секундах
    Maximum_interval: INTEGER is 2
            -- Максимальная пауза между соседними сегментами в секундах
invariant
    in_list: (1 "= index) and (index "= schedule.segments.count)
    in_schedule: schedule.segments.item (index) = Current
    next_in_list: (next /= Void) implies (schedule.segments.item (index + 1) = next)
    no_next_iff_last: (next = Void) = (index = schedule.segments.count)
    non_negative_rating: rating >= 0
    positive_times: (starting_time > 0) and (ending_time " 0)
    sufficient_duration: ending_time - starting_time >= Minimum_duration
    decent_interval: (next.starting_time) - ending_time >= Maximum_interval
end

Каждый сегмент "может определить" график, частью которого он является, и свое положение с помощью запросов schedule и index. Он содержит запросы starting_time и ending_time, к которым можно добавить и запрос duration, с инвариантом, связывающим длительность сегмента с временем начала и завершения. Такая избыточность допустима в системном анализе, добавление избыточных свойств отражает особенности, представляющие интерес для пользователей или разработчиков. Отношения между избыточными элементами фиксируются в соответствующих инвариантах. Инварианты in_list и in_schedule отражают позицию сегмента в списке сегментов и в графике.

Сегмент также "знает" о следующем сегменте. Инварианты отражают требования последовательности: next_in_list указывает, что если позиция текущего сегмента - i, то следующего - i +1. Инвариант no_next_iff_last служит признаком того, является ли данный сегмент последним в графике.

Два последних инварианта выражают ограничения на продолжительности: sufficient_duration определяет минимальную продолжительность в 30 секунд для фрагмента программы, являющегося сегментом, а decent_interval - максимальную паузу в 2 секунды между двумя последовательными сегментами (темный экран).

Спецификация класса содержит два недостатка, которые почти наверняка придется устранить при следующей итерации. Во-первых, время и продолжительность выражаются целыми числами (в секундах). Целесообразнее применить более абстрактный вариант - использование библиотечных классов DATE, TIME и DURATION. Во-вторых, понятие SEGMENT охватывает два отдельных понятия: фрагмент телевизионной программы и временное планирование. Разграничение этих понятий достигается добавлением в SEGMENT атрибута

content: PROGRAM_FRAGMENT

и нового класса PROGRAM_FRAGMENT для описания программного фрагмента вне зависимости от его положения в графике. Компонент duration нужно поместить в PROGRAM_FRAGMENT, а новое инвариантное предложение в SEGMENT примет вид:

content.duration = ending_time - starting_time

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

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

Программы и реклама

Развивая далее понятие SEGMENT, введем два вида сегментов: программные и коммерческие (рекламные сегменты). Это наводит на мысль использовать наследование.

Программные сегменты и рекламные паузы

Рис. 9.2. Программные сегменты и рекламные паузы

Использование наследования в процессе анализа всегда вызывает подозрения. Не следует создавать лишних классов там, где достаточно введения отличительного свойства. Руководящий критерий был дан при рассмотрении наследования: действительно ли каждый предложенный класс реально соответствует отдельной абстракции, характеризующейся специфическими особенностями? В данном случае использование нового класса оправдано, поскольку разумно предложить специальные свойства классу COMMERCIAL, как будет показано ниже. Наследование сопровождается преимуществами открытости: можно позже добавить нового наследника INFOMERCIAL (рекламный ролик) для описания сегмента другого вида.

Начнем работу над COMMERCIAL:

indexing
    description: "Рекламный сегмент"
deferred class COMMERCIAL inherit
    SEGMENT
        rename sponsor as advertizer end
feature
    primary: PROGRAM is deferred
            -- Программа, с которой связан данный сегмент
    primary_index: INTEGER is deferred
            -- Индекс сегмента primary
    set_primary (p: PROGRAM) is
                -- Связать рекламу с p
        require
            program_exists: p /= Void
           same_schedule: p.schedule = schedule
            before: p.starting_time <= starting_time
        deferred
        ensure
            index_updated: primary_index = p.index
            primary_updated: primary = p
        end
invariant
    meaningful_primary_index: primary_index = primary.index
    primary_before: primary.starting_time <= starting_time
    acceptable_sponsor: advertizer.compatible (primary.sponsor)
    acceptable_rating: rating <= primary.rating
end

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

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

  • Если программа имеет спонсора, то в течение ее показа приемлема далеко не любая реклама. Никто не будет рекламировать Pepsi-Cola в телешоу, спонсируемом Coca-Cola. Можно выполнить запрос к некоторой базе данных о совместимости.
  • Рейтинг рекламы должен соответствовать программе: реклама бульдозера неуместна в передаче для малышей.

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

Деловой регламент

Мы видели, как инварианты и другие утверждения могут охватить семантические ограничения прикладной области. В терминах анализа это называют деловым регламентом: для класса SCHEDULE можно планировать размещение сегмента только в будущем; в классе SEGMENT определено, что пауза между двумя сегментами не должна превышать установленного значения; в COMMERCIAL рейтинг рекламы должен соответствовать рейтингу передачи.

Принципиальным вкладом ОО-метода является возможность для таких правил использования утверждений и принципов Проектирования по Контракту наряду с заданием структуры.

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

Оценка

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

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

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

Александр Качанов
Александр Качанов
Япония, Токио
Янош Орос
Янош Орос
Украина, Киев