Файл: 14. Компонентная разработка приложений. Введение в компонентные модели.pdf

Добавлен: 20.10.2018

Просмотров: 1303

Скачиваний: 9

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

 

 

14. Компонентная разработка приложений. Введение в компонентные 

модели 

Как уже было отмечено ранее, одной из основных тенденций последних 

20  лет  является  использование  инструментальных  средств  быстрой 

разработки  приложений  (RAD  –  Rapid  Application  Development).  Все  эти 

пакеты (Delphi, C++ Builder, MS Visual Studio, Java NetBeans и т.д.) основаны 

на  использовании  так  называемых  компонентов  –  объектов  со 

специальными  свойствами  и  специальным  поведением.  Такие  объекты-

компоненты имеют следующие особенности: 

  каждый объект-компонент решает свою логически законченную задачу 

  компоненты  взаимодействуют  друг  с  другом  по  четко  определенным 

правилам 

  компоненты  могут  встраиваться  в  состав  RAD-инструментов  и 

многократно  использоваться  в  рамках  технологии  визуальной 

разработки приложений 

Ясно,  что  понятие  «объект»  более  широкое,  чем  понятие  «компонент»: 

любой  компонент  является  объектом,  но  не  любой  объект  является 

компонентным. Наличие большого числа стандартных компонентов является 

основой  современных  средств  разработки  и  позволяет  существенно 

уменьшить  объем  «ручного»  кодирования  и  в  итоге  сократить  сроки 

разработки. 

Одним  из  первых  примеров  эффективности  данного  подхода  является 

компонентная 

разработка 

оконного 

пользовательского 

интерфейса 

программы.  Для  реализации  этого  интерфейса  разработаны  десятки 

стандартных  компонентов,  от  очень  простых  до  достаточно  сложных. 

Компоненты  могут  выбираться  из  библиотеки,  визуально  настраиваться  и 

при необходимости – допрограммироваться.  

Например,  стандартный  компонент  «Управляющая  кнопка»  (Button  по-

ихнему:)) имеет следующий предопределенный функционал: 


background image

 

 

  умеет  отображать  себя  на  форме  в  заданном  месте,  с  заданными 

размерами и  заданным стилем  

  умеет  реагировать  на  выбор  пользователем  с  помощью  мыши, 

клавиатуры, а в современных реализациях – просто пальцем 

Разработчику остается лишь написать код, который будет выполняться в 

ответ на выбор кнопки – все остальное уже реализовано! 

Еще пример – стандартный компонент «Список строк» (ListBox): 

  способен хранить включенные в него строки (контейнер, однако:)) 

  умеет добавлять и удалять строки 

  умеет отображать свои строки на форме  

  умеет сортировать строки 

  умеет реагировать на выбор строк пользователем 

Другими  часто  используемыми  компонентами  являются  поля  ввода, 

таблицы, переключатели, деревья, текстовые надписи и др. 

Конечно,  разработкой  интерфейса  использование  компонентов  не 

ограничивается.  Еще  одним  чрезвычайно  важным  и  мощным  применением 

компонентного  подхода  является  разработка  приложений,  использующих 

базы  данных.  Подключение  к  базам  разных  типов,  доступ  к  хранящимся  в 

них  данным,  отображение  этих  данных  –  все  реализовано  в  стандартных 

компонентах.  Это  позволяет  создавать  простые  приложения  вообще  без 

написания программного кода. 

Ясно, 

что 

компоненты-объекты 

являются 

экземплярами 

соответствующих  классов,  в  которых  описана  вся  функциональность  таких 

объектов.  Компонентные  классы  являются  частным  случаем  обычных 

классов и описываются с помощью специальных правил. Набор таких правил 

иногда  называют  компонентной  моделью.  Не  претендуя  на  полноту 

изложения,  выделим  лишь  два  основных  момента,  характерных  для  всех 

основных компонентных моделей: 


background image

 

 

  обязательное  закрытие  внутренних  данных  объекта-компонента  и 

организация  контролируемого  доступа  к  ним  с  помощью 

специальных элементов – так называемых свойств 

  наделение  компонентных  объектов  способностью  реагирования  на 

события 

Эти  общие  моменты  в  разных  компонентных  моделях  реализованы  по-

разному.  Далее  для  сравнения  приводится  краткое  описание  трех  основных 

компонентных моделей. Начинается описание с компонентной модели пакета 

Delphi как одной из первых (отметим, что аналогичная модель реализована в 

пакете  C++  Builder),  а  затем  уже  описываются  более  поздние  модели 

JavaBeans  и  .NET Framework. 

 

В  компонентной  модели  Delphi  доступ  к  внутренним  закрытым  полям 

данных реализуется с помощью специальных элементов – свойств (property). 

Общая схема использования свойств: 

 

объявить внутреннее закрытое поле данных; 

 

объявить  и  реализовать  один  или  два  метода  доступа  (обычно  – 

защищенные); 

 

объявить  с  помощью  директивы  property  открытое  свойство  с 

указанием  (с помощью  директив  read  и write)  используемых методов 

доступа.  

Схематично это реализуется следующим программным кодом: 

TSomeClass = class 

   private  FSomeField : <тип поля>;                 // закрытое поле данных 

   protected  function  GetSomeField : <тип поля>;     // методы доступа 

   protected  procedure  SetSomeField (aField : <тип поля>); 

   public  property  SomeField : <тип поля>         // свойство как таковое 

read  GetSomeField   write  SetSomeField;    

end

Простейшая реализация методов доступа: 


background image

 

 

function  TSomeClass.GetSomeField : <тип>; 

begin 

   result := FSomeField; 

end 

procedure  TSomeClass.SetSomeField (aField : <тип>); 

begin 

   if  aField <> FSomeField  then  FSomeField := aField; 

end

Синтаксически свойства в программе используются следующим образом: 

 

как обычно, объявляется и создается объектная переменная 

          var  SomeObject : TSomeClass; 

          SomeObject :=  TSomeClass.Create; 

 

свойству присваивается некоторое значение в соответствии с его типом 

          SomeObject.SomeField := <значение>; 

 

значение свойства присваивается некоторой переменной 

          <переменная> := SomeObject.SomeField; 

При  этом  последние  два  присваивания  переводятся  компилятором  в 

вызовы  соответствующих  методов  доступа:  в  первом  случае  для 

присваивания  значения  вызывается  Set-метод,  во  втором  для  получения 

значения свойства – Get-метод.  

В  простейшем  случае  допускается  отсутствие  методов  доступа  с 

указанием в описании свойства имени соответствующего закрытого поля: 

TSomeClass = class 

   private  FSomeField : <тип поля>;                  

   public  property  SomeField : <тип поля>  

                                read  FSomeField   write  FSomeField;    

end

Вместо  директивы  public  при  описании  свойств  часто  используется 

директива  published,  которая  определяет  так  называемые  «публикуемые» 

свойства. Особенность таких свойств состоит в том, что в процессе создания 


background image

 

 

приложения  они  видны  в  окне  Инспектора  Объектов  (Object  Inspector)  и 

могут изменяться разработчиком.  

 

Второй  важный  (и  более  сложный)  аспект  создания  компонентных 

классов  связан  с  тем,  что  объекты-компоненты  должны  поддерживать 

механизм  обработки  событий,  на  котором  основаны  все  современные 

универсальные  операционные  системы.  Для  этого  с  каждым  объектом 

связывается  набор  характерных  для  него  событий  и  предоставляется 

возможность  для  каждого  такого  события  реализовать  необходимый 

программный код обработки. 

Технически  для  этого  в  состав  компонентного  класса  вводятся 

специальные  закрытые  поля,  в  которых  могут  храниться  адреса 

подпрограмм,  отвечающих  за  обработку  соответствующих  событий.  Такие 

поля принципиально отличаются от обычных полей и поэтому объявляются с 

помощью  специального  так  называемого  процедурного  типа.  Каждый 

процедурный  тип  имеет  свое  имя,  описывается  специальным  образом  и 

фактически  определяет  группу  подпрограмм  с  одинаковым  набором 

параметров. Например: 

type  TSomeProcType = procedure(параметры) of  object;   

Переменной типа TSomeProcType в качестве значения можно присвоить 

имя  любого  метода,  у  которого  набор,  тип  и  порядок  параметров 

соответствует описанному. Кратко можно сказать, что в объектной модели 

Delphi событие является свойством процедурного типа.  

В  базовой  библиотеке  пакета  Delphi  объявлено  несколько  стандартных 

процедурных  типов,  используемых  для  создания  обработчиков  событий. 

Простейшим  типом  является  тип  TNotifyEvent,  который  вводит  класс 

методов-обработчиков,  имеющих  только  один  параметр  Sender  типа 

TObject, через который передается указатель на объект-источник события: 

      TNotifyEvent = procedure (Sender : TObject)  of  object;