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

Добавлен: 20.10.2018

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

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

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

 

 

public  void  addKeyListener(KeyListener  kl) { . . . }; 

public  void  removeKeyListener(KeyListener  kl) { . . . }; 

public  void  addMouseListener(MouseListener  ml) { . . . }; 

public  void  removeMouseListener(MouseListener  ml) { . . . }; 

Информация 

о 

всех 

свойствах 

компонентного 

класса 

и 

зарегистрированных событиях сохраняется в файле и с помощью механизма 

отражения  доступна  в  процессе  визуального  создания  программы.  Здесь 

также  используется  такое  важное  свойство  Bean-компонентов,  как 

сохраняемость (persistence), т.е. способность компонентов записывать себя 

во  внешние  файлы  с  восстановлением  своей  структуры  в  более  позднее 

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

является  стандартным  для  всех  объектов  Java,  реализующих  интерфейс 

Serializable. Этот механизм превращает объект в поток байтов, помещаемый 

во  внешний  файл.  Очень  важно,  что  механизм  сериализации  позволяет 

сохранять и восстанавливать объектную структуру любой сложности, т.е. со 

всеми внутренними объектными свойствами. 

В заключение рассмотрим компонентную модель платформы .NET. Эта 

платформа  в  основном  предназначена  для  разработки  приложений  для 

систем  семейства  Windows.  Основу  этой  технологии  составляет  библиотека 

классов  Framework  Class  Library,  которая  в  настоящее  время  включает  в 

себя  несколько  тысяч  классов,  с  помощью  которых  можно  создавать 

практически любые типы Windows-приложений.  

Одной из особенностей процесса разработки .NET-приложений является 

языковая независимость (относительная, конечно): исходный текст можно 

написать на любом языке, поддерживающем данную технологию (C#, J#, VB, 

C++),  после  чего  соответствующий  компилятор  переводит  этот  текст  в 

универсальное  промежуточное  представление.  Это  представление 

описывается  с  помощью  специального  языка  IL  (Intermediate  Language), 

немного  похожего  на  язык  ассемблера.  После  этого  отдельные  IL-модули 

могут  объединяться  в  так  называемую  сборку  (assembly),  которая 


background image

 

 

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

сборка помимо кода на IL-языке содержит метаданные с полным описанием 

используемых  в  программе  типов  и  классов.  При  запуске  программы  на 

выполнение IL-код переводится на машинный язык конкретного процессора 

и  выполняется.  Этими  процессами  управляет  специальное  средство  .NET-

технологии  –  так  называемая  Common  Language  Runtime  (CLR, 

общеязыковая среда выполнения). 

Компонентная  модель  платформы  .NET  аналогична  рассмотренным 

ранее моделям языков Java и Delphi. При описании класса вводятся закрытые 

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

полям.  Описание  свойства  должно  включать  объявление  одного  или  двух 

методов доступа с обязательными именами get и set

Например: 

public  class  MyClass 

{  private  int  myfield;   // закрытое поле 

    public  int   MyField  // соответствующее свойство 

    {   get   {  return   myfield;  }  //  метод доступа 

    {   set    {  myfield = value;  }  // метод доступа 

   } 

. . .  другие поля и их свойства . . . 

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

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

объектов. 

Как  уже  отмечалось  выше,  компонент  как  строительный  блок 

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

Обработка  событий  в  .NET-приложениях  основана  на  использовании 

указателей на функции-обработчики, но по сравнению с пакетом  Delphi эти 

указатели реализованы более надежным способом – с помощью специальных  

объектов, называемых делегатами (delegate). Объект-делегат может хранить 


background image

 

 

указатель  на  функцию  только  конкретного  заранее  заданного  типа,  что 

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

повышает надежность приложения. 

Базовым  классом  для  реализации  делегатов  является  класс 

MulticastDelegate, в котором вводится возможность хранения  любого числа 

указателей на функции и все необходимые для этого методы. На основе этого 

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

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

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

приложения,  то  без  использования  среды  выполнения  CLR  обойтись 

невозможно. 

Класс-делегат  описывается  неявно  с  помощью  служебных  слов, 

например (в языке C#) – с помощью директивы delegate. Синтаксис описания 

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

работы возложена на компилятор. При описании класса-делегата указывается 

прототип  метода,  на  который  будут  ссылаться  объекты-экземпляры  этого 

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

методов,  которые  имеют  ровно  один  параметр  строкового  типа  и  не 

возвращают результат (void): 

delegate   void   MyDelegat (string   st); 

После  этого  надо  создать  объект-делегат  с  помощью  неявного 

конструктора,  передав  ему  в  качестве  параметра  имя  метода,  на  который 

должен ссылаться объект-делегат: 

MyDelegat   myDel = new  MyDelegat (myObj.MyMetod); 

Здесь  myObj  –  объект  класса,  в  котором  реализован  пользовательский 

метод  с  именем  MyMetod.  Для  нашего  примера  этот  метод  обязательно 

должен  иметь  ровно  один  параметр  строкового  типа!  Если  попытаться 

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

сообщение об ошибке. 


background image

 

 

Пусть  для  наглядности  этот  метод  MyMetod  просто  лишь  выводит  на 

экран текстовую строку, передаваемую ему через входной параметр st. Тогда 

для  вызова  этого  метода  с  помощью  делегата  достаточно  оформить 

следующую простую конструкцию: 

myDel (“ Hello from delegate”); 

Конечно,  в  данном  примере  использование  делегатов  кажется 

надуманным,  поскольку  метод  MyMetod  можно  вызвать  непосредственно. 

Однако  для  реализации  обратных  вызовов,  возникающих  при  выполнении 

программы  этот  механизм  весьма  удобен.  Именно  по  этой  причине  он  и 

используется  при  обработке  событий.  При  этом  важным  моментом  в 

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

делегатов  в  списки.  Для  добавления  и  удаления  элементов  в  эти  списки 

можно  использовать  методы  Combine  и  Remove  базового  класса 

MulticastDelegate.  Для  удобства  использования  этих  методов  в  языке  C# 

переопределены операторы  +=  и  -= . Вместо них компилятор подставляет 

вызовы  методов  Combine  и  Remove.  Например,  если  вместе  с  методом 

MyMetod  объявить  другой  метод  MyMetod2  с  такими  же  параметрами  (в 

данном  случае  –  с  одним  параметром  строкового  типа),  то  его  можно 

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

myDel += myObj.MyMetod2; 

После  этого  указанное  выше  обращение  к  делегату  приведет  к  вызову 

уже двух разных методов.  

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

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

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

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

пользователи  компонента  могут  использовать  для  добавления  и  удаления 

событий  в  списке  вызова  делегата.  Поскольку  эти  операции  являются 

достаточно стандартными, в язык С# введена специальная директива event, с 


background image

 

 

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

составляющие: 

class   MyComponent: ParentComponent 

{   public   event   MyDelegat   MyEvent; 

     . . . . . . . . .  }; 

После этого пользователи компонента должны создать его экземпляры и 

добавить обработчики события MyEvent следующим образом: 

MyComponent   myComp = new  MyComponent ( ); 

myComp += new  MyDelegat (myComp.MyMetod); 

В  заключение  отметим,  что  для  создания  полноценных  компонентов 

необходимо  придерживаться  ряда  простых  рекомендаций  по  оформлению 

делегатов и методов-обработчиков событий.