КАТЕГОРИИ:
АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника
|
Класс приложенияДля завершения рассмотрения класса APPLICATION рассмотрим несколько возможных реализационных решений: · Будем нумеровать состояния приложения числами от 1 до n. Заметьте, эти числа не являются абсолютными свойствами состояний, они связаны с определенным приложением, поэтому в классе STATE нет атрибута "номер состояния". Вместо этого, одномерный массив associated_state, атрибут класса APPLICATION, задает состояние, связанное с заданным номером. · Представим функцию переходов transition еще одним атрибутом - двумерным массивом размерности n * m, где m - число возможных пользовательских выборов при выходе из состояния. · Номер начального состояния хранится в атрибуте initial и устанавливается в подпрограмме choose_initial. Для конечных состояний мы используем соглашение, что переход в псевдосостояние 0 означает завершение сессии. · Процедура создания в классе APPLICATION использует процедуры создания библиотечных классов ARRAY и ARRAY2. Последний описывает двумерные массивы и построен по образцу ARRAY ; его процедура создания make принимает четыре аргумента, например create a.make (1, 25, 1, 10), а его подпрограммы item и put используют два индекса - a.put (x, 1, 2). Границы двумерного массива a можно узнать, вызвав a.lower1 и так далее. Вот определение класса, использующего эти решения: indexing description: "Интерактивные приложения, управляемые панелями"class APPLICATION creation makefeature -- Initialization make (n, m: INTEGER) is -- Создает приложение с n состояниями и m возможными выборами do create transition.make (1, n, 1, m) create associated_state.make (1, n) endfeature -- Access initial: INTEGER -- Номер начального состоянияfeature -- Basic operations execute is -- Выполняет сессию пользователя local st: STATE; st_number: INTEGER do from st_number := initial invariant 0<= st_number; st_number <= n until st_number = 0 loop st := associated_state.item (st_number) st.execute -- Вызов процедуры execute класса STATE. -- (Комментарии к этой ключевой инструкции даны в тексте.) st_number := transition.item (st_number, st.choice) end endfeature -- Element change put_state (st: STATE; sn: INTEGER) is -- Ввод состояния st с индексом sn require 1 <= sn; sn <= associated_state.upper do associated_state.put (st, sn) end choose_initial (sn: INTEGER) is -- Определить состояние с номером sn в качестве начального require 1 <= sn; sn <= associated_state.upper do initial := sn end put_transition (source, target, label: INTEGER) is -- Ввести переход, помеченный label, -- из состояния с номером source в состояние target require 1 <= source; source <= associated_state.upper 0 <= target; target <= associated_state.upper 1 <= label; label <= transition.upper2 do transition.put (source, label, target) endfeature {NONE} -- Implementation transition: ARRAY2 [STATE] associated_state: ARRAY [STATE] ... Другие компоненты ...invariant transition.upper1 = associated_state.upperend -- class APPLICATIONОбратите внимание на простоту и элегантность вызова st.execute. Компонент execute класса STATE является эффективным (полностью реализованным) поскольку описывает известное общее поведение состояний, но его реализация основана на вызове компонентов: read, message, correct, display, process, отложенных на уровне STATE, эффективизация которых выполняется потомками класса, такими как RESERVATION. Когда мы помещаем вызов st.execute в процедуру execute класса APPLICATION, у нас нет информации о том, какой вид состояния обозначает st, но благодарястатической типизации мы точно знаем, что это состояние. Далее включается механизм динамического связывания и в период исполнения st становится связанной с объектом конкретного вида, например RESERVATION, - тогда вызовы read, message и других царственных особ автоматически будут переключаться на нужную версию. Значение st, полученное из associated_state, представляет полиморфную структуру данных ( polymorphic data structure), содержащую объекты разных типов, все из которых согласованы (являются потомками) со STATE. Текущий индекс st_numberопределяет операции состояния.
Вот как строится интерактивное приложение. Приложение должно быть представлено сущностью, скажем air_reservation, класса APPLICATION. Необходимо создать соответствующий объект: create air_reservation.make (number_of_states, number_of_possible_choices)Далее независимо следует определить и создать состояния приложения, как сущности классов-потомков STATE, либо новые, либо уже готовые и взятые из библиотеки повторного использования. Каждое состояние s связывается с номером i в приложении: air_reservation.put_state (s, i).Затем одно из состояний выбирается в качестве начального: air_reservation.choose_initial (i0)Для установления перехода от состояния sn к состоянию с номером tn, с меткой l используйте вызов: air_reservation.enter_transition (sn, tn, l)Это включает и заключительные состояния, для которых по умолчанию tn равно 0. Затем можно запустить приложение: air_reservation.execute_session.При эволюциях системы можно в любой момент использовать те же подпрограммы для добавления состояний и переходов. Конечно же, можно расширить класс APPLICATION, изменяя сам класс или добавляя новых потомков, включив новые функциональные возможности - удаление, моделирование или любые другие.
|