50580

Понятие компонента, компонентной модели, компонентно-ориентированного программирования

Лекция

Информатика, кибернетика и программирование

Что представляет собой компонент Компонент от лат. В программировании компонент это кирпичик программы состоящий из свойств properties методов methods и событий events. Свойства дают возможность управлять видом и поведением компонента методы использовать возможности предоставляемые компонентом а события реагировать на происходящие внутри компонента события программировать реакцию компонента на внешние события и т.

Русский

2014-01-26

61 KB

34 чел.

Понятие компонента, компонентной модели, компонентно-ориентированного программирования

1. Что представляет собой компонент  

Компонент (от лат. сomponent - составляющий)- составная часть, элемент чего-либо. В программировании компонент— это "кирпичик" программы, состоящий из свойств (properties), методов (methods) и событий (events). Свойства дают возможность управлять видом и поведением компонента, методы — использовать возможности, предоставляемые компонентом, а события— реагировать на происходящие внутри компонента события, программировать реакцию компонента на внешние события и т. д.

Разработка программы с помощью компонентов называется компонентно-ориентированным программированием.

Начнем с определения термина компонент в программировании. Компонент — это независимый модуль, предназначенный для многократного использования и предоставляемый пользователю в двоичном формате. Это определение описывает четыре ключевых характеристики компонента. Рассмотрим их по очереди.

Компонент определен как независимый модуль. Это означает, что каждый компонент вполне самодостаточен. Другими словами, компонент обеспечивает полный набор функций. Его внутренняя работа закрыта для "внешнего мира", но при этом реализация может быть изменена без последствий для кода, в котором используется этот компонент.

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

Компонент представляет собой отдельный модуль. Это очень важно. С точки зрения клиента компонент выполняет конкретную функцию или набор функций. Функциями компонента, может воспользоваться любое приложение, но сам компонент не является автономной программой.

Наконец, компонент должен быть представлен в двоичном формате. Это принципиально важно. Хотя использовать компонент могут многие клиенты, они не имеют доступа к его исходному коду. Функциональность компонента открыта для клиентов только посредством его public-членов. Другими словами, именно компонент управляет тем, какие функции оставлять открытыми для клиентов, а какие — держать "под замком”.

2. Компонентная модель

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

До создания С# и среды .NET Framework большинство компонентов были СОМ-компонентами. Модель СОМ была разработана для традиционной среды Windows и языка С++. Поэтому она в принципе не в состоянии использовать преимущества новых методов управления памятью, которые реализованы в С# и .NET Framework. Как следствие, СОМ-контракт был довольно трудным для реализации и ненадежным. К счастью, С# и среда . NET Framework лишены практически всех проблем своих предшественников.

3. Что представляет собой С#-компонент

Благодаря особенностям работы средств языка С#, любой его класс полностью соответствует общему определению компонента. Например, будучи скомпилированным, класс (в его двоичной форме) можно использовать в различных приложениях. Но значит ли это, что любой класс является компонентом? Ответ: нет. Для того чтобы класс стал компонентом, он должен следовать компонентной модели, определенной средой .NET Framework. К счастью, этого совсем не трудно добиться: такой класс должен реализовать интерфейс System.ComponentModel.IComponent. При реализации интерфейса IComponent компонент удовлетворяет набору правил, позволяющих компоненту быть совместимым со средой . Framework.

Несмотря на простоту реализации интерфейса IComponent, во многих ситуациях лучше использовать альтернативный вариант - класс System.ComponentModel.Component. Класс Component обеспечивает стандартную реализацию интерфейса IComponent. Он также поддерживает другие полезные средства, свойственные компонентам. Опыт показывает, что большинству создателей компонентов удобнее выводить их из класса Component, чем самим реализовать интерфейс IComponent, поскольку в первом случае нужно попросту меньше программировать. Следовательно, в С# на создание компонента не требуется "героических усилий" со стороны программиста.

4. Контейнеры и узлы

С С#-компонентами тесно связаны две другие конструкции: контейнеры и узлы.

Контейнер — это группа компонентов. Контейнеры упрощают программы, в которых используется множество компонентов.

Узел позволяет связывать компоненты и контейнеры.

5. Интерфейс IComponent

Интерфейс IComponent определяет правило, которому должны следовать все компоненты. В интерфейсе IComponent определено только одно свойство и одно событие. Вот как объявляется свойство Site:

ISite Site{ get; set; }

Свойство Site получает или устанавливает узел компонента. Узел идентифицирует компонент. Это свойство имеет null-значение, если компонент не хранится в контейнере.


Событие, определенное в интерфейсе IComponent, носит имя Disposed и объявляется так:

event EventHandler Disposed

Клиент, которому нужно получить уведомление при разрушении компонента, регистрирует обработчик событий посредством события Disposed. Интерфейс IComponent также наследует интерфейс System.IDisposable, в котором определен методDispose():

void Dispose().

Этот метод освобождает ресурсы, используемые объектом.

6. Класс Component

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

В классе Component определен конструктор только по умолчанию. Обычно
программисты не создают объект класса
Component напрямую, поскольку основное назначение этого класса — быть базовым для создаваемых компонентов.

В классе Component определено два открытых свойства. Объявление первого из них, свойства Container, такое:

public IContainer Container {get; }

Свойство Container возвращает контейнер, который содержит вызывающий компонент. Если компонента нет в контейнере, возвращается значение null. Следует помнить, что свойство Container устанавливается не компонентом, а контейнером.

Второе свойство, Site, определено в интерфейсе IComponent. В классе Component оно реализовано как виртуальное:

public virtual ISite Site{ get; set; }

Свойство Site возвращает или устанавливает объект типа ISite, связанный с компонентом. Оно возвращает значение пи11, если компонента в контейнере нет. Свойство  Site устанавливается не компонентом, а контейнером.

В классе Component определено два открытых метода. Первый представляет собой переопределение метода ToString(). Второй, метод Dispose() , используется в двух формах. Первая из них такова:

public void Dispose();

Метод Dispose(), вызванный в первой форме, освобождает любые ресурсы, используемые вызывающим компонентом. Этот метод реализует метод Dispose(), определенный в интерфейсе System.IDisposable. Для освобождения компонента и занимаемых им ресурсов клиент вызывает именно эту версию метода Dispose().

Вот как выглядит вторая форма метода Dispose(),:

protected virtual public void Dispose(bool how);

Если параметр how имеет значение true , эта версия метода освобождает как управляемые, так и неуправляемые ресурсы, используемые вызывающим объектом.

Если how равно значению false, освобождаются только неуправляемые ресурсы. Поскольку эта версия метода Dispose() защищена (protected), ее нельзя вызвать из кода клиента. Поэтому клиент использует первую версию. Другими словами, вызов первой версии метода Dispose() генерирует обращение к методу Dispose(bool how).

В общем случае компонент, в котором больше нет необходимости, переопределяет версию Dispose(bool how), если он содержит ресурсы, которые нужно освободить. Если компонент не занимает никаких ресурсов, то для его освобождения достаточно стандартной реализации метода Dispose(bool how), определенной в классе Component.

Класс Component наследует класс MarshalByRefObject, который используется в том случае, когда компонент создается вне локальной среды, например в другом процессе или на другом компьютере, связанном с первым по сети. Для обмена данными (аргументами методов и возвращаемыми значениями) должен существовать механизм, который определит способ пересылки данных. По умолчанию принимается, что информация должна передаваться по значению, но при унаследовании класса MarshalByRefObject данные будут передаваться по ссылке. Таким образом, С#-компонент обеспечивает передачу данных по ссылке.

7. Компоненты: достоинства и недостатки

Компонентно-ориентированная разработка имеет свои сильные и слабые стороны. Несомненными достоинствами является повторная используемость кода, согласованность пользовательского интерфейса, возможность быстрой и продуктивной разработки программ. Именно компоненты позволяют программистам составлять конечный продукт из "кирпичиков", не вдаваясь в детали реализации конкретного компонента. Конечно, наборы классов, используемые при объектно-ориентированном подходе, тоже дают возможность повторного использования кода, но компоненты делают повторное использование кода совершенно естественным.

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

Компоненты дают возможность независимой разработки частей интерфейса. Изменения внутри компонента не затрагивают код модулей, в которых он используется. Разработка нескольких независимых классов дает примерно те же результаты, за исключением одной проблемы. Среди программистов средней

б


квалификации наблюдается тенденция перемешивать функциональность классов, путая методы одного класса с другим. Компоненты разделяют код более качественно.

Свойства компонентов позволяют наиболее эффективно объяснить другому программисту, как использовать компонент. Специальные редакторы свойств позволяют быстро настроить вид и поведение компонентов.

Наконец, накопив достаточное количество компонентов, можно действительно быстро создать визуальный интерфейс программы, фактически, не написав более ни строчки кода!

Чем же придется заплатить за все это? Как это не удивительно звучит, но платить придется объектно-ориентированным подходом. Возможность гибкого управления поведением компонентов с помощью событий провоцирует написанием "событийно-ориентированного" кода. Пусть, например, нам нужен компонент для отображения цветных строк. Объектно-ориентированный подход обязывает нас создать наследника класса ListBox и, перекрыв метод Paint(), реализовать отрисовку цветных строк. Возможность реализовать событие OnPaint и не создавать никаких классов подталкивает многих программистов к использованию событий в ущерб объектно-ориентированному подходу. Именно "подталкивает", т. к. никто не мешает создать новый компонент, умеющий рисовать цветные строки на основе существующего компонента ListBox. Такой подход и будет наиболее верным — ведь такие компоненты можно использовать повторно!

Еще одна плата за удобство — необходимость иметь гибкие компоненты. Нет смысла писать компонент, рисующий только строки красного цвета. Такой компонент будет затруднительно использовать где-либо, кроме той программы, для которой он изначально предназначался. Гораздо правильнее написать компонент, рисующий строки заданного цвета, а сам цвет вынести в его свойства (или как-то хранить внутри самой строки). Вот такой компонент можно использовать в любой программе. Такая гибкость требует некоторых дополнительных усилий, необходимость затратить которые не всегда очевидна при разработке одной программы, но вполне окупается при повторном использовании компонента.

Подводя итог этому рассуждению, можно сказать, что цель разработки нового компонента—создание новой функциональности, являющейся независимой, но гибко настраиваемой частью, допускающей повторное использование.


Визуальные и невизуальные компоненты в дизайнере формы

Библиотека .NET Framework имеет два типа компонентов: визуальные и невизуалъные. Визуальные компоненты являются элементами пользовательского интерфейса. Это, например, компоненты: кнопка (Button), выпадающий список (ComboBox) или метка (Label). Невизуальные компоненты не имеют пользовательского интерфейса и не могут располагаться на форме. Дизайнер Visual Studio располагает их внизу окна дизайнера. Такими компонентами являются, например, компоненты работы с базами данных, таймер (Timer), компонент работы с последовательным портом (SerialPort) и др.


 

А также другие работы, которые могут Вас заинтересовать

60547. Загальна характеристика системи освіти США 55 KB
  У більшості селищ відкривалося граматичні школи в яких готували учні для подальшого навчання в університетах. Як результат до кінця IX століття школи змогли запропонувати учням вивчення латині тваринництва арифметики курси ведення домашнього господарства і догляду за дітьми та хворими.
60548. Ваше будущее в ваших руках 43.5 KB
  Цель занятия: формирование коммуникативных организаторских умений лидерских качеств. Информирование Один из законов лидера Лидер излучает вдохновляющую силу.
60554. Добірка уроків алгебри в 9 класі по темі «Нерівності» 907 KB
  Основні властивості числових нерівностей. Сформулювати основні властивості числових нерівностей. Приклади опорний конспект Знаки нерівностей. Приклади числових нерівностей План проведення лекції...