Главная страница / 30. Объектно-ориентированные методы анал...: 30.5. Пример разработки к...

30.5. Пример разработки консольного приложения в технологии объектно-ориентированного подхода

Навигация по разделу:

30.5.1. Диаграмма прецендентов UML
30.5.2. Диаграмма последовательности UML для прецедента
30.5.3. Диаграмма классов UML для прецендента «перевести р-ичную строку в число»
30.5.4. Текст приложения на языке Object Pascal

Рассмотрим пример проектирования и реализации программы, предназначенной для преобразования р-ичного числа (р в интервале от 2 до 16), представленного строкой в числовом формате, в технологии ООП.

Проект программы опишем с помощью диаграммы прецедентов, диаграммы последовательностей и диаграммы классов. Реализуем проект в форме консольного приложения на языке Object Pascal в среде программирования Delphi.

30.5.1. Диаграмма прецендентов UML

↑ Наверх

Программа реализует единственный прецедент: полученную от пользователя р-ичную строку преобразует в числовой формат.


Рис. 30.9. Диаграмма прецедентов UML

Сценарий прецедента (рис. 30.9): пользователь вводит с клавиатуры основание системы счисления и действительное число, представленное в этой системе счисления. Программа проверяет введенные значения. Если они верны (основание находится в диапазоне от 2 ло 16, во введенном числе нет недопустимых символов), то программа осуществляет преобразование введенного числа в десятичную систему счисления и отображает результат на экране монитора, в противном случае программы выдает сообщение об ошибке и завершает свою работу.

30.5.2. Диаграмма последовательности UML для прецедента

↑ Наверх

Для реализации прецедента мы создаем два объекта: один объект класса TInOut осуществляет ввод исходной строки, проверку строки на соответствие заданному формату и вывод результата; второй объект класса TConvertPToDec осуществляет преобразование введенной строки в числовой формат. Обмен сообщениями между объектами представлен на диаграмме последовательности (рис. 30.10).


Рис. 30.10. Диаграмма последовательности UML для прецедента

30.5.3. Диаграмма классов UML для прецендента «перевести р-ичную строку в число»

↑ Наверх

Между классом TinOut и классом TConvertPtoDec существует отношение зависимости, которое на диаграмме (рис. 30.11) изображено в виде штриховой стрелки. Это отношение возникает в силу того, что объекты класса TinOut вызывают операции объектов класса TConvertPtoDec для преобразования введенного числа в десятичную систему счисления. 


Рис. 30.11. Диаграмма классов UML для прецедента «перевести р-ичную строку в число»

30.5.4. Текст приложения на языке Object Pascal

↑ Наверх

Приложение состоит из головной программы POOP и модуля UOOP. В головной программе описан класс TInOut, который отвечает за ввод исходных данных и вывод результата. В модуле UOOP описан класс TConvertPtoDec, который отвечает за преобразования числа, представленного в системе счисления с основанием р, в десятичную систему.

Класс TInOut инкапсулирует в себе поля p, Np, mistake для хранения данных и методы, предназначенные для обработки полей. Методы в классе представлены заголовками трех процедур по именам: OutPutResult, CheckInputFormat, Input и заголовком специального метода конструктора по имени Create. Интерфейс класса – это те поля и методы, к которым могут обращаться объекты этого класса, представлен разделом с уровнем доступа public. Реализация класса – это те поля и методы, которые недоступны объектам этого класса, она представлена разделом с уровнем доступа private. В случае класса TInOut все методы составляют интерфейс класса, а поля – его реализацию.

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

//Текст головной программы.
//-----------------------------------------------------
program POOP;
//-----------------------------------------------------
//Перевод р - ичного числа представленного строкой в
//число. р от 2 до 16.
//Технология ООП
{$APPTYPE CONSOLE}
//-----------------------------------------------------
uses
   SysUtils,
   UOOP in 'UOOP.pas';

//-----------------------------------------------------
type
//-----------------------------------------------------
   TInOut = Class
//-------------------------------------------------
   public
//-------------------------------------------------
      procedure OutPutResult(r: TConvertPtoDec);
      //Вывод десятичное представление р - ичного числа
      //-------------------------------------------------
      procedure CheckInputFormat();
      //Контроль формата ввода
      //-------------------------------------------------
      procedure Input();
      //Ввод р-ичного числа
      //-------------------------------------------------
      constructor Create(p: integer = 16);
      //-------------------------------------------------
   private
      //-------------------------------------------------
      p: integer;//Основание системы счисления
      //-------------------------------------------------
      Np:String;//исходное р-ичное число
      //-------------------------------------------------
      mistake: integer;//Номер ошибочной позиции в р-ичном числе
      //-------------------------------------------------
   end;
//-----------------------------------------------------
const
   FirstS =['0'..'9','A'..'F','a'..'f','-','+'];
   Another = FirstS + [','];
//-----------------------------------------------------
constructor TInOut.Create(p: integer = 16);
begin
   self.p:= p;
   mistake:= 0;
end;
//-----------------------------------------------------
procedure TInOut.Input;
//Ввод р-ичного числа
begin
   write('p = ');
   Readln(p);
   write('Str',p,' = ');
   readln(Np);
end;

//-----------------------------------------------------
procedure TInOut.CheckInputFormat;
//Контроль формата ввода
var
   i: integer;
begin
   for i:= 1 to Length(Np) do begin
      if (i = 1) and not (Np[1] in FirstS) then begin mistake:= 1; exit; end;
      if (i <> 1) and not (Np[i] in Another) then begin mistake:= i; exit; end;
   end;
end;
//-----------------------------------------------------
procedure TInOut.OutPutResult;
//Вывод десятичное представление р - ичного числа
begin
   if mistake = 0
      then begin //Формирование и вывод строки результата
                     writeln('number = ',r.Convert(Np,p) :8:4);
               end
      else //вывод сообщения об ошибке
         writeln('input mistake position ', mistake);
end;
//-----------------------------------------------------
var
   c: TInOut;
   f: TConvertPtoDec;
//-----------------------------------------------------
begin
   c:= TInOut.Create(16);//Создание объекта класса TInOut.
   f:= TConvertPtoDec.Create; //Создание объекта класса
                                                     //TConvertPtoDec.
   c.Input();//Ввод исходных данных
   c.CheckInputFormat;//Контроль формата исходных данных
   c.OutPutResult(f);//Преобразование и вывод результата
   readln;
end.

Текст модуля.
//-----------------------------------------------------
unit UOOP;

//-----------------------------------------------------
interface
//-----------------------------------------------------
type
//-----------------------------------------------------
   TConvertPtoDec = class//отвечает за преобразование числа
   //-------------------------------------------------
   public
   //-------------------------------------------------
      function Convert(Np: String;p: integer):real;
      //Формирование результата
   private
      //-------------------------------------------------
      function PCharToInt(d: Char):integer;
      //переводит символ, изображающий цифру в её
      //числовое представление в системах счисления с
      //основаниями от 2 до 16
      //-------------------------------------------------
      function PStrToInt(r: String; b:integer):integer;
      //перевод целого - строка r в её числовое
      //представление в с. сч. с основанием b
      //-------------------------------------------------
      function PStrToFrac(f: String; b:integer): Real;
      //перевод дроби - строка f в её числовое
      //представление в с. сч. с основанием b
   end;
//-----------------------------------------------------
implementation
//-----------------------------------------------------
function TConvertPtoDec.PCharToInt(d: Char):integer;
//переводит символ, изображающий цифру, в её числовое
//представление в системах счисления с основаниями от 2 //до 16
begin
   result:= 0;
   case d of
   '0'..'9': Result:= Ord(d)- Ord('0');
   'A'..'F': Result:= Ord(d)- Ord('A') + 10;
   'a'..'f': Result:= Ord(d)- Ord('a') + 10;
   end;
end;
//-----------------------------------------------------
function TConvertPtoDec.PStrToInt(r: String; b:integer):integer;
//перевод целое строка s в её числовое
//представление в с. сч. с основанием b
var n: integer; w: integer;
begin
   result:= 0;
   n:= Length(r);
   w:= 1;
   while n <> 0 do begin
      Result:= Result + PCharToInt(r[n])*w;
      w:= w*b;
      Delete(r,n,1);
      n:= Length(r);
   end;
end;
//-----------------------------------------------------
function TConvertPtoDec.PStrToFrac(f: String; b:integer): Real;
//перевод дробь строка f в её числовое
//представление в с. сч. с основанием b
var n: integer; w : Real;
begin
   result:= 0;
   n:= Length(f);
   w:= 1/b;
   while n <> 0 do begin
      Result:= Result + PCharToInt(f[1])*w;
      w:= w/b;
      Delete(f,1,1);
      n:= Length(f);
   end;
end;
//-----------------------------------------------------
function TConvertPtoDec.Convert(Np: String;p: integer):real;
//Формирование результата p-основание системы счисления
var
   Ip: String;//целая часть исходного р-ичного числа
   Fp: String;//дробная часть исходного р-ичного числа
   signe: integer;//Знак числа
   z: integer;//позиция разделителя в р-ичном числе
begin
   Ip:='';//целая часть исходного р-ичного числа
   Fp:='';//дробная часть исходного р-ичного числа
   signe:= 1;//Знак числа
   if Np[1]='-'
      then begin signe:= -1; delete(Np,1,1) end
      else signe:= 1;
   z:= Pos(',',Np);
   if z <> 0
      then begin
         Ip:= Copy(Np,1,z - 1);
         Fp:= Copy(Np,z + 1,Length(Np) - z);
         result:= PStrToInt(Ip, p) + PStrToFrac(Fp, p)
      end
      else begin Ip:= Np; result:= PStrToInt(Ip, p); end;
   if signe < 0
      then result:= result*signe;
end;

end.
//-----------------------------------------------------