Добавил:
sergeevpavel0406@mail.ru СОВА Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Информатика в техническом университете / Информатика в техническом университете. Основы программирования

.pdf
Скачиваний:
72
Добавлен:
06.03.2018
Размер:
13.53 Mб
Скачать

12. Разработка библиотеки интерфейсных компонентов

procedure Enter; virtual; {при нажатии на Enter

...}

end;

 

 

 

 

 

Implementation

 

 

 

 

Constructor TMenu.Init;

 

 

 

Var i:integer;

 

 

 

Begin

 

 

 

 

 

inherited Init(axl, ayI, ax2, ау2, aattr, axt, ayt, atext);

 

nalt:=n;

{количество реально используемых пунктов меню}

for i:=I

to nalt do

 

 

 

 

masalt[i]Jnit(w[i-l],xly wfi-IJ.yl,

wfi'lj.x2,

w[i-lj.y2,

End;

 

wfi'ljMttr, wfi'JJ.xt,

wfi'IJ.yt,

wfi-lj.text);

 

 

 

 

 

Procedure TMenu.Draw;

 

 

 

Var i:integer;

 

 

 

Begin { очищаем экран}

 

 

 

TextBackGround(O);

 

 

 

TextColor(l);

 

 

 

Windowd 1M25);

Clrscr;

 

 

inherited Draw;

{выводим основное окно}

for

i;=l to nalt do masaltfiJ.Draw; {выводим окна пунктов}

End;

 

 

 

 

 

Procedure

TMenu.Run;

 

 

 

Var chl,ch2;char;

 

 

 

temp:integer;

 

 

 

Begin

 

 

 

 

 

Draw;

 

 

 

 

 

npos:=nalt;

 

 

 

masalt[npos].Setattr(71);

 

 

repeat

 

 

 

 

 

chl:=Readkey; {читаем код клавиши}

 

ifchl

=#0 then ch2: =Readkey;

 

 

case chl of

 

 

 

#0: case ch2 of

 

 

 

 

#75:begin

{перемещение курсора влево}

 

 

temp:'=npoS'l;

 

 

 

 

iftemp^O

then temp:=nalt;

{закольцовываем}

 

 

masaltfnposJ.SetattrfJJ3);

{убираем выделение}

 

 

masaltftempfSetattr(71);

{выделяем пункт}

 

 

npos:=temp;

 

 

 

 

end;

 

 

 

 

#77:begin

{перемещение курсора вправо}

 

 

temp:=npos+I;

 

 

 

 

iftemp=nalt+J then temp:=l; {закольцовываем}

371

Часть 2. Объектио-ориентироваииое программирование

masalt[npos].Setattr(113); {убираем выделение} masalt[temp].Setattr(71); {выделяем пункт} npos:=temp;

end;

end; #13: begin

masalt[npos].Setattr(113); {убираем выделение}

Enter; {при нажатии Enter - выполняем пункт} Draw; {выводим главное меню} masalt[npos].Setattr(71); {выделяем пункт меню}

end;

end

until((npos=nalt)and(chl=#13))or(chl=#27);{jxo завершения работы} End;

Procedure TMenu.Enter; {абстрактный метод выполнения пунктов}

Begin end; End.

К л а с с T F o r m описываем в модуле Form. Инициализацию объект­ ных полей - окон ввода также будем выполнять с использованием типизиро­ ванных констант.

Unit Form;

Interface

Uses crt, WinJnputMenu; Type TForm=Object(TMenu)

ninput:integer; {количество полей ввода} masinp:array[1..5] ofTInput; {массив полей ввода}

constructor Initfaxl, ayl, ax2, ay2,aattr, axt, ayt:integer;atext:str80; n:integer; const wl:array of TWin;k:integer; const w2:array of TInput);

procedure Draw; virtual; {вывод окна} procedure Clear; {очистка окон ввода}

procedure Input; {ввод информации из окон ввода} end;

Implementation Constructor TForm.Init;

Var i:integer; Begin

inherited Init(ax1,ayl,ax2, ay2, aattr,axt,ayt,atext, n, wl); ninput: =k; {количество задействованных окон ввода}

372

12. Разработка библиотеки интерфейсных компонентов

for i:-l to ninput do masmpfiJJnit(w2fi'JJ.xJ, w2fi'IJ.yI,

w2fi'lj,x2, w2[i'l].y2, w2[i'l],attr, w2[i-l],xt, w2[i],yt,w2[i'l]Jext, w2[i'l]Anp.xl, w2[i'l]Anp.yl, w2[i-l].inp.x2, w2fi'JJJnp.y2,

w2[i-l],inp.attn w2[i'l]Anp.xU w2[hl].inp.yt, w2fhlj, inp,text);

End;

 

Procedure TForm.Draw;

 

Var i:integer;

 

Begin

{выводим основное окно}

inherited Draw;

for i:=l to nalt do masalt[i].Draw;

{выводим окна пунктов}

for i:=l to ninput do masinpfiJ.Draw; {выводим окна ввода}

End;

 

Procedure TForm. Clear;

 

Var i:integer;

 

Begin

{чистим окна ввода}

for i:=I to ninput do masinpfi],Clear;

End;

 

Procedure TForm.Input;

 

Var i:integer;

 

Begin

 

Clear;

for i:=I to ninput do masinp[iJ,Input; {вводим данные}

End;

End

12.4. Создание программы с использованием библиотеки интерфейсных компонентов

В параграфе 12.1 для программы «Записная книжка» уже была выполне­ на декомпозиция интерфейсной части предметной области (рис. 12.7). Оста­ лось учесть взаимодействие профаммы с файлом: открытие, запись инфор­ мации и ее поиск. Будем считать, что все эти действия выполняет объект Файл. Этот объект должен обрабатывать сообщения: Открыть/создать, Доба­ вить и Найти. На рис. 12.11 показан результат объектной декомпозиции всей предметной области профаммы.

Проектирование и реализация объекта Файл. Для реализации объек­ та Файл разработаем класс XBase (рис. 12.12).

373

Часть 2. Объектно-ориентированное программирование

Главное

меню

Активизировать.--^

^""^^-^^^^^Активизировать

 

Активизировать^--.^^^

 

 

\

 

 

 

Ввод

Добавление

 

 

Поиск

имени файла

записей

 

 

записей

 

Добавить

 

Н а й т и / ^

\

 

 

 

 

Открыть/создать ^^^-«.^.^^

^

Активизировать\

Г ж^

г1

Файл

Сообщение об отсутствии

^ данных ^

Рис. 12.11. Диаграмма объектов предметной области программы

Этот класс должен хранить файловую переменную f, через которую бу­ дет осуществляться доступ к файлу.

Для поиска данных класс будет включать поля исходных данных поис­ ка: p_family ~ фамилия и ропате - имя, ключи kl, к2, которые устанавлива­ ются в зависимости от того, заданы или нет фамилия или имя и поля резуль­ татов поиска family, name, telefon. Кроме того, класс должен включать метод открытия существующего или создания нового файла Open, метод добавле­ ния записей Add, метод поиска первой подходящей записи Find и метод по­ иска следующих подходящих записей FindNext.

Наибольший интерес представляют функции поиска информации, кото­ рые в соответствии с заданием должны обеспечивать поиск по неполным данным. При этом поля Фамилия и Имя могут быть заданы, а могут быть пропущены, могут совпадать, а могут не совпадать. Всего возможно 2"* = 16 вариантов. В пяти случаях результат поиска положителен (табл. 12.1), т.е. за­ писи считаются удовлетворяющими заданным условиям. Эти случаи можно объединить в одно логическое выражение:

ff = (kl л к2 л кЗ л к4) v (к1л к2 л кЗ) v ( i l л к2 л к4),

TBase

f, family, name, telefon, p_family, p_name, kl, k2 Init(), Open(), Add(), Find(), FindNext(), Closefi:)

Рис. 12.12. Класс TBase

где л - соответствует логиче­ скому «и», а V - логическому «или».

Именно это выражение и заложено в метод поиска для определения «подходящих» записей.

374

12. Разработка библиотеки интерфейсных компонентов

 

 

 

 

 

Т а б л и ца

12.1

 

Фамилия

Имя

Фамилия

Имя

Результат

 

указана

указано

совпадает

совпадает

поиска

 

 

kl

к2

кЗ

к4

fr

 

 

Да

Да

Да

Да

Да

 

 

Да

Да

Да

Нет

Нет

 

1

Да

Да

Нет

Да

Нет

 

 

Да

Да

Нет

Нет

Нет

 

!

Да

Нет

Да

Да

Да

 

 

Да

Нет

Да

Нет

Да

 

 

Да

Нет

Нет

Да

Нет

 

 

Да

Нет

Нет

Нет

Нет

 

 

Нет

Да

Да

Да

Да

 

 

Нет

Да

Да

Нет

Нет

 

 

Нет

Да

Нет

Да

Да

 

 

Нет

Да

Нет

Нет

Нет

 

 

Нет

Нет

Да

Да

Нет

 

 

Нет

Нет

Да

Нет

Нет

 

 

Нет

Нет

Нет

Да

Нет

 

 

Нет

Нет

Нет

Нет

Нет

1

 

Ниже приведен текст модуля Base, содержащего описание данного клас-

са.

 

 

 

 

 

 

 

Unit Base;

 

 

 

 

 

 

Interface

 

 

 

 

 

 

Type str30=string[30];

 

 

 

 

 

rec=record

 

 

 

 

 

rfamily rname, rtelefon:str30;

 

 

 

 

end;

 

 

 

 

 

Type TBase=Object

 

 

 

 

 

ffile

ofrec;

 

 

 

 

 

family

name, telefon:str30; {результаты поиска}

 

 

 

pjdmilypjiame:str30;

{данные поиска}

 

 

 

kly k2:boolean;

{ключи поиска}

 

 

 

procedure Open(fname:str30);

{открытие/создание файла}

 

procedure Add(afamilyaname,atelefon:str30); {добавление записей}

 

function Find(afamilyaname:str30):boolean; {поиск первого}

 

375

Часть 2. Объектно-ориентированное программирование

function FindNext:boolean;

{поиск следующего}

procedure Closef;

{закрытие файла}

End:

 

Implementation

 

Procedure TBase.Open;

 

Begin

 

Assign(f,fname); {инициализация файловой переменной}

{$Ч

Resetф:

{$1-^} {открытие с проверкой существования} iflOResultoO then ReWrite(f): {создание файла}

End;

Procedure TBase.Add; Var r:rec;

Begin

Seek(f,FileSize(f)); {ycTSLueiBnnBeiQM файловый указатель на конец файла}

r.rfamily:^afamily;

{создаем запись}

кгпате.'^апате;

 

 

 

к rtelefon: =atelefon;

 

 

Write(f,rJ;

 

{выводим запись в файл}

End;

 

 

 

Function XBase. Find;

 

 

 

Begin

 

 

 

Close(f);

 

{закрываем файл}

ReSetф;

 

{открываем файл для чтения}

pjdmily:=afamily;

 

{сохраняем данные поиска}

р_пате:=апате;

 

 

 

kJ:=p_family<> ";

 

{устанавливаем два ключа поиска}

к2:=р_пате<> 'V

 

 

 

Find:=FindNext;

 

 

{ищем запись по ключам}

End;

 

 

 

Function TBase.FindNext;

 

 

Var r:rec;

 

 

 

кЗ, k4, ff:boolean;

{ключи поиска и его результат}

Begin

 

 

 

ff:^false; {ключ поиска «запись не найдена»}

while not Eof(f) and

notjfdo

begin

 

 

 

Reader);

 

 

 

k3:=pjamily=r,rfamily;

{строим еще два ключа поиска}

к4: =р_пате =г тате;

376

12. Разработка библиотеки интерфейсных компонентов

if(kl and к2 and кЗ and к4) {выбираем записи}

or (not kl and k2 and k4) or (kl and not k2 and кЗ) then

begin

{ключ поиска «запись найдена»}

ffi'^true;

family:^r.rfamily;

{копируем результаты поиска}

пате:=к тате; telefon: =кrtelefon;

end

end;

FindNext:=ff; {возвращаем ключ поиска} end;

Procedure TBase.Closef; begin

С1о8еф; {закрываем файл} end;

End,

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

На рис. 12.13 представлена полная диаграмма классов программы, на которой показано наследование интерфейсных классов от описанных в биб­ лиотеке и уточнены их ассоциации с классом TBase.

Класс TIName будет использован для реализации объекта Ввод имени файла. Он переопределяет метод Error класса TInput, задавая свой вариант проверки правильности введенной информации.

Класс TMain строится для реализации объекта Главное меню. Он пере­ определяет метод Enter, конкретизируя поведение программы при выборе пунктов главного меню. Количество пунктов меню регулируется соответст­ вующей инициализацией поля nalt. Добавляемое поле may логического типа будет использовано для контроля открытия файла.

Классы TAdd и TFind будут использованы для реализации форм Добав­ ление и Поиск. Очевидно, что они должны переопределять абстрактный ме­ тод Enter прародителя - класса TMenu. Кроме этого в классе TFind необходи­ мо переопределить метод ввода, который должен обеспечить ввод информа­ ции не из всех полей, а только из поля фамилии и поля имени, и добавить ме­ тод Show для вывода найденных данных (телефона и, при поиске по непол­ ным данным, имени или фамилии) в окно поиска.

377

Часть 2, Объектно-ориентированное программирование

т.т

"ТГ

TIName

 

 

IL

 

TForm

TMain

 

 

may

Error()

 

Т

 

2_

 

 

Enter(), Init()

 

TAdd

 

TFind

 

Enter()

Enter(), Input(), Show()

 

V Формирует

 

Открывает •

XBase

Л Обрабатывает

 

Рис. 12.13. Диаграмма классов программы «Записная книжка»

Для реализации объекта Сообщение об отсутствии данных нового клас­ са создавать не нужно, используем непосредственно класс TMessage.

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

Ниже представлен полный текст программы.

Program Memory;

Uses crt,WmJnput,Message,Menu,Form,Base;

{объявление классов - потомков библиотечных классов}

Туре TMain-Object (ТМепи)

{главное меню}

тау:Ьоо1еап;

{признак открытия файла}

Procedure Enter; virtual;

end;

 

Type TIName=Object(TInput)

{ввод имени файла}

Function Error:boolean; virtual; {проверка имени файла}

end;

 

Type TAdd=Object(TForm)

{форма для добавления записей}

Procedure Enter; virtual; {завершение ввода одной записи} end;

378

12, Разработка библиотеки интерфейсных компонентов

Туре TFind=ObJect(TForm)

{форма для поиска телефонов}

Procedure Input; virtual;

{ввод данных поиска}

Procedure Enter; virtual;

{поиск одной записи}

Procedure Show;

 

 

{вывод результата поиска в окна}

end;

 

 

 

{объявление объектов-переменных}

Var M:TMain;

 

{объект Главное меню}

N:TIName;

{объект Ввод имени файла}

A:TAdd;

{объект Добавление записей}

F:TFind;

{объект Поиск записей}

ND:TMessage;

{объект Сообщение об отсутствии данных}

B:TBase;

{объект Файл}

{описание дополнительных методов}

Procedure TMain.Enter; {обработка выбора пунктов главного меню}

Begin

case проз of l:begin

N.Draw; {выводим окно ввода}

NJnput; {вводим имя файла, проверяя его допустимость} B,Open(N.inpJext); {если файл существует, то открываем,

иначе - создаем} may:=true; {устанавливаем признак открытия файла }

end;

2:if may then {если определен файл данных } A.Run; {осуществляем добавление записей}

Зц/тау then {если определен файл данных } FRun; {осуществляем поиск записей}

end;

End;

Function TIName.Error; {проверка имени файла}

Var L'integer;

Begin l:=Pos(\ \ inp.Text);

if 1=0 then l:=length(inp.Text); if(l>0) and e<==8) then Error:=fahe

else Error:=true;

End;

Procedure TAdd.Enter; {обработка пунктов меню добавления}

Begin casenpos of

l:begin

Input; {вводим фамилию, имя и телефон}

B,Add(masinpf]J. inp. text, masinp[2]. inp, text, masinp[3J.inp.text); {записываем в файл}

379

Часть 2. Объектно-ориентированное программирование

end; end; {case}

End;

Procedure TFindEnter; {обработка пунктов меню поиска}

Begin case npos of ]:begin

Input; {вводим фамилию и имя } ifB,Find(masinp[l]AnpJexUmasinp[2]Anp.text) then Show

else

ND.Run;

{выводим сообщение об отсутствии данных }

end;

 

 

 

2:begin

 

 

 

ifB.FindNext

then Show

else

ND.Run;

{выводим сообщение об отсутствии данных }

end;

 

 

 

end;

 

 

 

End;

 

 

 

Procedure TFindJnput;

{ввод данных для поиска информации}

Begin

 

 

 

Clear;

 

{очищаем поля ввода}

masinp[l].Input;

{вводим фамилию}

masinp[2],Input;

(вводим имя}

End;

 

 

 

Procedure TFind.Show; {вывод найденной информации в окно}

Begin

 

 

 

 

 

Clear;

 

 

 

 

 

masinpfJJ,inpJext:=B,family;

masinpflJ.Draw;

{выводим фамилию}

masinpf2], inp. text: name;

masinp[2J,Draw; {выводим имя}

masinpf3JjnpJext:=BJelefon;

masinp[3J,Draw;

{выводим телефон}

End;

 

 

 

 

 

{описание констант для инициализации полей-массивов}

Const menul:array[l.J]

ofTWin=

 

 

 

((xl:I0;yl:14;x2:23;y2:18;attr:113;xt:3;yt:2;

 

 

 

text:'Создать /

открыть

книэюку*),

(xl:26;yl:14;x2:39;y2:18;attr:113;xt:4;yt:2;

 

 

text: 'Записать

телефон'),

 

(xl:42;yl:14;x2:55;y2:18;attr:113;xt:5;yt:2;

 

 

 

text: 'Найти

телефон'),

 

(xl:58;yl:14;x2:71;y2:18;attr:113;xt:4;yt:2;

 

 

 

text: 'Завершить

работу'));

 

menu2:array[L.2]

ofTWin^

 

 

 

 

((xl:28;yl:18;x2:38;y2:21;attr:113;xt:2;yt:2;text:

'Добавить'),

(xl:42;yl:18;x2:52;y2:2I;attr:113;xt:2;yt:2;text:

'Выход'));

380