Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Virtual float temperatureAt(int Minute);

Читайте также:
  1. Alternative to the Virtual World
  2. Combining multiagent systems and virtual environments
  3. Currency Exchange: Floating Rate Vs. Fixed Rate
  4. Float (someone) a loan
  5. Float pi(void)
  6. Float-type hydrometer for measuring battery specific gravity
  7. Floating Houses

protected:

};

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

На самом деле в смысле поведения нам надо нечто большее, чем просто зависимость температуры от времени. Пусть, например, известно, что на 60-й минуте должна быть достигнута температура 150°C, а на 180-й - 90°C. Для ввода данных будем использовать функцию bind(). Теперь нам нужно узнать, какой должна быть температура на 120-й минуте? Это требует линейной интерполяции, так что требуемое от абстракции поведение усложняется. Для получения таких сведений введена функция temperatureAt().

Вместе с тем, управления нагревателем, поддерживающим требуемый режим остывания, мы от этой абстракции не требуем[3]. Мы предпочитаем разделение понятий, при котором нужное поведение достигается взаимодействием трех объектов: режима остывания (экземпляра класса TTemperatureRamps), нагревателя (экземпляра класса THeaters) и управляющего органа (экземпляра класса TRampControllers ). Класс TRampControllers можно определить так:

class TRampControllers

{

public:

TRampControllers():

~ TRampControllers();

void process( TTemperatureRamps TemperatureRamp);

int schedule( TTemperatureRamps TemperatureRamp);

private:

}; .

Операция process() обеспечивает основное поведение этой абстракции; ее назначение - передать график изменения температуры нагревателю, установленному в конкретном месте. Например, объявим:

TTemperatureRamps* objTemperatureRamp;

TRampControllers* objTRampController; .

Теперь, построив объекты, задав пару точек, определим режим остывания, загрузим его в контроллер и запустим процесс:

objTemperatureRamp - > bind(150, 60);

objTemperatureRamp - > bind(90, 180);

objTRampControllers - > process(objTemperatureRamp); .

В этом примере objTRampControllers – некоторый агент, ответственный за выполнение температурного плана, он использует объект objTemperatureRamp как специалиста по планированию температурного режима (сервер). Эта связь проявляется хотя бы в том, что objTRampControllers явно получает objTemperatureRamp в качестве параметра одной из своих операций.

Сделаем одно замечание по поводу нашего стиля. На первый взгляд может показаться, что наши абстракции - лишь объектные оболочки для элементов, полученных в результате обычной функциональной декомпозиции. Пример операции schedule() (расписание) показывает, что это не так. Объекты класса TRampControllers имеют достаточно интеллекта, чтобы определять расписание для конкретных режимов остывания, и мы включаем эту операцию как дополнительное поведение нашей абстракции. В некоторых энергоемких технологиях (например, плавка металлов) можно существенно выиграть, если учитывать остывание установки и тепло, остающееся после предыдущей плавки. Поскольку существует операция schedule(), клиент может запросить объект objTRampControllers, чтобы тот рекомендовал оптимальный момент запуска следующего нагрева.

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

Актер (Actor - это деятель, исполнитель; а исполнитель ролей, это и есть актер). Объект может воздействовать на другие объекты, но сам никогда не подвергается воздействию других объектов, это соответствует понятию «активный объект».

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

Агент. Такой объект может выступать как в активной, так и в пассивной роли; как правило, объект-агент создается для выполнения операций в интересах какого-либо объекта-актера или объекта-агента.

Сервер предоставляет некоторые услуги, в которых нуждаются и которые запрашивают актеры и агенты. Поэтому, в противоположность серверу, актеров и агентов часто называют клиентами.

Видимость. Пусть есть два объекта А и B. Чтобы А cмог установить связь с объектом B, надо, чтобы B был в каком-то смысле видим для А. Мы можем не заботиться об этом на стадии анализа, но когда дело доходит до реализации системы, мы должны обеспечить видимость связанных объектов.

В предыдущем примере объект objTRampController видит объект objTemperatureRamp, поскольку оба они объявлены в одной области видимости и потому, что objTemperatureRamp передается объекту objTRampController в качестве параметра. В принципе есть следующие четыре способа обеспечить видимость:

- сервер глобален по отношению к клиенту;

- сервер (или указатель на него) передан клиенту в качестве параметра операции;

- сервер является частью клиента;

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

Какой именно из этих способов выбрать - зависит от тактики проектирования.

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

- последовательный - функционирование пассивного объекта обеспечивается в присутствии только одного активного процесса, в этом случае синхронизация вырождается;

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

- синхронный - функционирование пассивного объекта обеспечивается в присутствии многих потоков управления; взаимное исключение обеспечивает сам пассивный объект (сервер).

В качестве примера защищенного подхода приведем распространенный прием синхронизации в случае использования коллективного ресурса:

Printer -> Open(); ; Printer -> Close(); или

Clipboard -> Open(); ; Clipboard -> Close() или

GlobalLock(h); ...; GlobalUnLock(h).

В приведенных примерах Open(), GlobalLock(h) означают заблокировать объект от одновременного обращения других клиентов. Многоточием обозначено выполнение над объектом (принтером, буфером обмена, памятью) необходимых нашему приложению действий. Наконец, Close(), GlobalUnLock(h) осуществляют разблокирование коллективного ресурса, который становится доступным другим приложениям. Обратим внимание на неудачное использование понятий: Open (открывать) обозначает блокирование (закрытие) постороннего доступа, Close (закрывать) обозначает разблокирование (открытие) постороннего доступа. Использование термина Lock (запирать) надо признать более удачным

1.2.3. Отношение агрегации. В то время как связи обозначают равноправные или «клиент-серверные» отношения между объектами, агрегация определяет отношения целого и части, приводящие к соответствующей иерархии объектов, причем, идя от целого (агрегата), мы можем придти к его частям. В этом смысле агрегация - специализированный частный случай ассоциации. На рис. 1.1 объект objTRampController имеет два отношения: связь с объектом objTemperatureRamp и атрибут h класса THeaters (нагреватель). В данном случае objTRampController - целое, a h - его часть. Другими словами, h - часть состояния objTRampController. Исходя из objTRampController, можно найти соответствующий нагреватель. Однако по h нельзя найти содержащий его объект (называемый также его контейнером), если только сведения о нем не являются случайно частью состояния h.


Агрегация

 

Рис. 1.1

Агрегация может означать физическое вхождение одного объекта в другой, но не обязательно. Самолет состоит из крыльев, двигателей, шасси и прочих частей. С другой стороны, отношения акционера с его акциями - это агрегация, которая не предусматривает физического включения. Акционер монопольно владеет своими акциями, но они в него не входят физически. Это, несомненно, отношение агрегации, но скорее концептуальное, чем физическое по своей природе. Аналогичными примерами являются пары: автомобиль и шофер; самолет и пилот.

Выбирая одно из двух - связь или агрегацию - надо иметь в виду следующее. Агрегация иногда предпочтительнее, поскольку позволяет скрыть части в целом. Иногда наоборот предпочтительнее связи, поскольку они слабее и менее ограничительные. Принимая решение, надо взвесить все.

Объект, являющийся атрибутом другого объекта (агрегата), имеет связь со своим агрегатом. Через эту связь агрегат может посылать ему сообщения. При добавлении в спецификацию класса TRampControllers описание нагревателя:

h: T Heater s ;

каждый объект objRampController будет иметь свой нагреватель.

Замечание. Мы должны создавать нагреватель при создании нового контроллера, так как сам этот класс не предусматривает вызова конструктора нагревателя по умолчанию. Противоположный подход используется в потомках класса TComponent.

Контрольные вопросы

1) Сформулируйте своими словами понятие «связи» между объектами.

2) Какими приемами можно обеспечить видимость между двумя объектами?

3) Какие существуют три подхода к синхронизации связи между объектами?

4) Сформулируйте своими словами понятие «агрегация» между двумя объектами.

5) Приведите примеры объектов, между которыми существуют отношения связи и агрегации.

 

Классы

1.3.1. Понятие класса. Понятия класса и объекта настолько тесно связаны, что невозможно говорить об объекте безотносительно к его классу. Однако существует важное различие этих двух понятий. В то время как объект обозначает конкретную сущность, определенную во времени и в пространстве, класс определяет лишь абстракцию существенного в объекте. Таким образом, можно говорить о классе «Млекопитающие», который включает характеристики, общие для всех млекопитающих. Для указания на конкретного представителя млекопитающих (кот Тютька) необходимо сказать «кот Тютька – млекопитающее».

В общепонятных терминах можно дать следующее определение класса: группа, множество или вид с общими свойствами или общим свойством, разновидностями, отличиями по качеству, возможностями или условиями. В контексте объектно-ориентированного анализа дадим следующее определение класса:

Класс - это некое множество объектов, имеющих общую структуру и общее поведение.

Любой конкретный объект является просто экземпляром класса. Что же не является классом? Объекты, не связанные общностью структуры и поведения, нельзя объединить в класс, так как по определению они не связаны между собой ничем, кроме того, что все они объекты.[4]

Класс в объектно-ориентированном программировании воплощается как абстрактный тип данных. В главе 2 показано, что объекты реальной жизни мы стараемся объединять в группы со сходными признаками, а группировка объектов и есть классификация. Теория абстрактных типов данных (глава 4) является теоретическим фундаментом построения системы классов. Перечислим основные принципы, заложенные в теорию абстрактных типов данных:

1) вводится понятие основы, которой можно сопоставлять некоторые множества;

2) вводятся операции, которые делятся на два вида – конструкторы и анализаторы; с помощью конструкторов мы можем формально построить элементы сопоставляемого основе множества; с помощью анализаторов мы можем сделать оценку свойств элементов сопоставляемого основе множества;

3) вводится описание свойств сопоставляемого основе множества; с помощью свойств мы выделяем интересующие нас подмножества;

4) вводятся правила построения иерархической системы абстрактных типов данных.

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

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

Важно отметить, что классы, как их понимают в большинстве существующих языков программирования, необходимы, но не достаточны для декомпозиции сложных систем. Некоторые абстракции так сложны, что не могут быть выражены в терминах простого описания класса. Например, пусть имеются выраженные в виде классов абстракции: графический интерфейс пользователя, база данных и система учета. Можно попытаться интегрировать перечисленные абстракции и построить объединенный класс, но повторной используемости и возможности наследования не получится: маловероятно, что заложенная в такой класс совокупность свойств понадобится в другом приложении. Строго говоря, то же самое в нашем примере можно сказать и про отдельные абстракции. Например, иметь универсальный и громоздкий интерфейс - плохая практика, так как большинству клиентов необходима только малая его часть. Более того, изменение одной части этого гигантского интерфейса требует обновления каждого из клиентов, независимо от того, затронуло ли его это изменение по сути. Вложенность классов не устраняет этих проблем, а только откладывает их. Лучше считать их некими совокупностями (кластерами) сотрудничающих классов. Будем называть такие кластеры категориями классов. Определение уровня абстракции, на котором интеграция переходит от классов к категориям классов, является очень нетривиальной задачей проектировщика. В качестве основного критерия можно взять потребность в повторной используемости создаваемого класса.

1.3.2. Интерфейс и реализация. Рассмотрим идею контрактного программирования: большие задачи надо разделить на много маленьких и перепоручить их мелким субподрядчикам. Нигде эта идея не проявляет себя так ярко, как в проектировании классов.

По своей природе, класс - это генеральный контракт между абстракцией и всеми ее клиентами. Выразителем обязательств класса служит его интерфейс, причем в языках с сильной типизацией потенциальные нарушения контракта можно обнаружить уже на стадии компиляции.

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

В основе разделения описания класса на две части используется уже известный прием абстрагирования: существенная для пользователя сторона описания класса находится в интерфейсе, а несущественная – в реализации. При этом интерфейс класса видим пользователям класса, а реализация класса - скрыта. Внутри интерфейса также имеются изобразительные средства, позволяющие более тщательно регулировать способ видимости содержимого класса. Мы можем разбить интерфейс класса на три части:

- открытую (public) - видимую всем клиентам без ограничений;

- защищенную (protected) - видимую самому классу и его подклассам;

- закрытую (private) - видимую только самому классу.

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

Состояние объекта задается в его классе путем определения констант или переменных, помещаемых в его защищенной или закрытой части. Тем самым свойства объекта инкапсулированы (помещены в оболочку), и изменения значений свойств осуществляются клиентом не напрямую, а посредством вызова методов. Инкапсуляция понимается как размещение свойств и методов класса в некоторой замкнутой оболочке, в которую одним клиентам разрешается заглянуть, а другим – нет.

В абстрактных типах данных (глава 4) определение типа данных задается модулем с двумя параметрами: описание теории, включающей сигнатуру и свойства, и описание реализации. В языках программирования интерфейс класса содержит только сигнатуру, а свойства типа данных должны обеспечиваться реализацией.

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

T DisplayItem objItem ;

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

Свойства, составляющие представление класса, известны под разными именами. В большинстве языков программирования их называют полями.

Контрольные вопросы

1) Сформулируйте своими словами понятие «класс».

2) Чем принципиально отличаются объект и класс?

3) Что представляет собой «категория классов»?

4) Объясните причину деления класса на две части – интерфейс и реализация?


Дата добавления: 2015-10-29; просмотров: 107 | Нарушение авторских прав


Читайте в этой же книге: Double dubFuelCell2Amperes(); | TransmitAmperes(); | Glossary of Nadsat Language | I was a wandering sheep. | I did not love... | Protestantism and Capitalism: A Causal Connection? | The Working of Competitive Markets | The Impact of Smith on Policy | Causes of the Wealth of Nations | Determinants of the Wealth of a Nation |
<== предыдущая страница | следующая страница ==>
Отношения между объектами| Отношения между классами

mybiblioteka.su - 2015-2024 год. (0.014 сек.)