ЗАДАНИЕ XXXIV
Тема: Обмен
сообщениями между объектами Цель: Овладеть приемами организации взаимодействия между объектами путем обмена сообщениями. |
Для работы необходимо:
выполнить предыдущую работу; | |
владеть основными приемами работы в MS Windows; | |
владеть основными приемами работы в Stratum 2000. |
Введение.
Объектно-ориентированный подход предполагает, что объекты взаимодействуют путем обмена сообщениями. Одним из способов обмена сообщениями является установка связей между объектами и передача информации по связям. Здесь связь между объектами постоянна, а обмен информацией по связям происходит перед началом нового такта вычислений. Этот способ был продемонстрирован в предыдущих работах.
Более универсальным способом взаимодействия объектов является непосредственная посылка сообщения объектом другому объекту или ряду объектов. Механизм сообщений позволяет изменить стандартную схему обработки модели и построить свою для обеспечения необходимого взаимодействия объектов
Для посылки сообщения используется функция
SendMessage(STRING ObjectName, STRING ClassName, [STRING VarName1, FLOAT VarName2...])
Функция осуществляет посылку сообщения объекту или группе объектов. Функция имеет переменное число аргументов для возможности указания произвольного числа связываемых переменных.
Параметры:
ObjectName Задает имя объекта (объектов), получающего сообщение.
ClassName Задает имя класса объекта (объектов), получающего сообщение.
VarName1 Имя связываемой переменной в объекте-отправителе сообщения.
VarName2 Имя связываемой переменной в объекте-получателе сообщения.
Возможно два способа передачи данных от объекта-отправителя к объекту-получателю: по адресу(
Addr InOut) и по значению(Value In, Value Out).При передаче значений по адресу переменные в объекте-отправителе и объекте-получателе связываются непосредственно в функции
SendMessage, например, SendMessage(“”,”ClassB”,”X”,”Y”), где X и Y по сути одна и та же переменная.Для передачи данных по значению необходимо организовать буфер обмена. Например, в объекте- отправителе (класс А) запишем
FLOAT buf, X1, Y1
//buf - буфер обмена
// объекту B надо послать значение переменной X1
// результат надо передать переменной Y1
buf:=X1
SendMesagge(“”,”B”,”buf”,”buf”)
//сейчас в buf возвращен результат обработки модели В.
Y1:=buf
В объекте-получателе (класс В) запишем
FLOAT buf,X2,Y2
X2:=buf
//вычисления, результат формируется в переменной Y2
//возвращаем результат через буфер
buf:=Y2
При обмене сообщениями между объектами возможна следующая ситуация: если объект А посылает сообщение объекту В, который в свою очередь посылает прямо или косвенно сообщение объекту А (например, как ответ на сообщение), то будет бесконечная рекурсия. Чтобы этого избежать, необходимо использовать флаги.
Задание 1. Создать Калькулятор для сложения и вычитания .
Создадим простой класс Calculator (Калькулятор с памятью), выполняющий операции сложение и вычитание. При реализации класса определим объект класса Control, который инициализирует объекты Add (сложение) и Sub (вычитание), посылая им сообщение через вызов функции SendMessage.
Объекты
Add и Sub обмениваются информацией с регистром Reg также через посылку ему сообщения.Порядок выполнения работы.
1. Создайте проект и поместите в его схему новый объект
Calculator.2 .Создайте схему объекта
Calculator и поместите в нее четыре новых объекта: Control, Reg, Add, Sub.3. Запишите модель класса Control :
STRING st,cod
FLOAT a,flag,flag1
flag:=1; flag1:=1
cod:=left(~st,1); a:=float(SubStr(~st,1,10))
switch
case(~cod==”+”)
//инициировать схему сложения
SendMessage(“”,”Add”,”a”,”a”,”flag1”,”_enable”); break
case(~cod==”-”)
//инициировать схему вычитания
SendMessage(“”,”Sub”,”a”,”a”,”flag1”,”_enable”); break //
case(~cod==”q”)
// закончить работу
CloseAll()
endswitch
4. Запишите модель класса
Add:FLOAT x,a,_enable
//получить первый операнд
SendMessage(“”,”Reg”,”x”,”x” )
//выполнить операцию
x:=~x+~a
// записать результат в регистр
SendMessage(“”,”Reg”,”x”,”sum” )
// выключить схему
_enable:=0
5. Аналогично запишите модель класса
Sub.6. Запишите модель класса
Reg:Float sum,x
x:=~sum
7. Для ввода команд и вывода результата поместите на схему объекты стандартных классов InputBox, NumberView, GraphicSpace и установите необходимые связи.
8. Проверьте работу модели. При необходимости измените порядок вычисления имиджей.
На рисунке 1 показана схема объекта Calculator.
Рис.1. Схема Calculator.
Обратите внимание на следующее.
Во-первых, объект управления (
Задание 2. Использование буфера обмена .
Создать калькулятор с памятью, выполняющий операции сложение и вычитание, причем результат хранится в Сумматоре, а операнд - в Регистре. Объект Управление посылает через сообщение операнд в Регистр, затем инициирует соответствующий операционный объект. Операционный объект связывается через сообщения с Сумматором и Регистром, получает данные, выполняет операцию и посылает результат в Сумматор. Добавим операцию “установить значение в Сумматоре”.
Порядок выполнения работы:
1. Создайте проект и поместите в его схему новый объект Calculator.
2. Создайте схему класса Calculator и поместите в нее пять новых объектов: Control, Add, Sub, Reg, Sum. Схема класса Calculator приведена на рисунке 2.
Рис.2. Схема класса Calculator.
3. Запишите модель класса Control :
STRING st,cod
float a,x,flag
flag:=1
st := InputBox("","","")
cod:=left(~st,1)
a:=float(SubStr(~st,1,10))
if(~cod=="q")
CloseAll()//выход
else //подготовка к работе соответствующей схемы
SendMessage("","Reg","a","a"); //запись в регистр
switch
case(~cod=="+")
SendMessage("","add","flag","_enable") //включить схему
case(~cod=="-")
SendMessage("","sub","flag","_enable") //включить схему
case(~cod=="=")
SendMessage("","Sum","a","x")
endswitch
endif
4. Запишите модель класса
Add.float a,x,buf //buf-буфер обмена
SendMessage("","Reg","a","buf") //получить значение "а" из регистра
SendMessage("","Sum","x","buf") //получить значение "х" из сумматора
x:=~x+~a
SendMessage("","Sum","x","x") //записать результат в сумматор
_enable:=0 //выключить схему
5. Аналогично запишите модель класса
Sub.6. Запишите модель класса
Reg.float a,buf //buf-буфер обмена
buf:=a
7. Запишите модель класса Sum.
float a,buf //buf-буфер обмена
buf:=a
8. Для визуализации результата поместите на схему объект
NumberView и свяжите его с Сумматором Sum. Создайте графическое пространство.9. Проверьте работу Калькулятора.
Дополнительные задания.
Добавьте в Калькулятор две операции: умножение и деление. Для этого, во-первых. наследуйте класс Control, внеся дополнения в текст его модели; во-вторых, создайте два новых класса: Mult и Del.
Измените модель Калькулятора так, чтобы объекты Add, Sub, Mult и Del получали значения операнда и записывали результат в регистр не путем посылки сообщения, а по связям с объектом Reg,