Назад Вперед Содержание

Пример 1

Проект «Светофор»

Светофор односторонний: светит только водителю, пешеход ориентируется на водителя.

Классы: Driver (водитель), Pedestrian (пешеход), TrafficLight (светофор) и Program (тестирующий)

В классе TrafficLight возникает два чередующихся статических события:

  1. Event1. Горит зеленый свет.
  2. Event2. Горит красный свет.

Класс Driver (водитель)

Поле: имя водителя.

Обработчик события Event1: Выводит сообщение: Имя водителя, еду. Проехавший водитель отписывается от обоих событий.

Обработчик события Event2: Выводит сообщение: Имя водителя, стою.

Класс Pedestrian (пешеход)

Поле: имя пешехода.

Обработчик события Event1: Выводит сообщение: Имя пешехода, стою.

Обработчик события Event2: Выводит сообщение: Имя пешехода, иду. Прошедший пешеход отписывается от обоих событий.

Класс TrafficLight (светофор)

Обработчик события Event1: Зеленым цветом выводит сообщение: Горит зеленый свет.

Обработчик события Event2: Красным цветом выводит сообщение: Горит красный свет.

Метод с параметром (целое число), по очереди генерирующий или событие Event1 (если число четное) или событие Event2 (если число нечетное)

Порядок написания кода программы:

1. Моделирование ситуации

Подготовим эти три простейших класса:

Класс TrafficLight и его методы:

ChangeLight (int i) – метод, в котором будет меняться свет. Этот метод событие генерирует, но мы его пока не описываем. Ставим заглушку.

Red() –обработчик события горит красный

Green() – обработчик события горит зеленый

Два других класса (с именами Driver и Pedestrian) тоже должны реагировать на возникновение события

В классе Driver:

Поле name, два конструктора, и два обработчика событий:

В классе Pedestrian:

Поле name, два конструктора, и два обработчика событий:

2. Оформление события.

В классе TrafficLight, в котором возникает событие, конструируем его.

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

Наше событие будет обрабатываться шестью методами, по два в каждом классе. Мы должны посмотреть сигнатуры этих методов (то есть посмотреть заголовки), и составить на основе этих сигнатур делегаты.

У наших обработчиков сигнатуры одинаковые: нет выходного значения и нет параметров. Поэтому делегат будет один.

Определяем делегат (назовем его Hadler). Опишем на его основе два события Event1 и Event2. Далее генерируем события в коде:

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

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

3. Подписка

Вернемся в точку входа программы main и создадим объект класса TrafficLight. Подпишем этот объект на оба события.

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

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

Выполним отработку:

Наблюдаем странную ситуацию: Водитель 1, который должен был уехать на зеленый свет, остался на нашем перекрестке. То же самое с пешеходами. Пешеходы никуда не уходят, водители никуда не уезжают.

Это происходит потому, что каждый из них по-прежнему подписан на оба события. А нам нужно, чтобы:

  1. водители отписывались от обоих событий, когда уезжают,
  2. пешеходы отписывались от обоих событий, когда переходят дорогу.

То есть это должно происходить в их классах. Для пешехода в методе Go класса Pedestrian. Для водителя в методе Ride класса Driver.

Но в этих классах у нас нет объекта svet светофор, от которого нужно отписываться. Поэтому придется в этом случае (далеко не всегда это нужно) события сделать статическими. Это даст нам возможность, при подписке и отписке не указывать имя объекта, а указывать имя класса.

В классе TrafficLight, опишем события, как статические.

Сразу появится много ошибок в тестирующем классе. Потому что наше событие мы присоединяли к объекту, а не к классу. А статическое событие не присоединяют к объекту. Поэтому сразу исправим эти ошибки в классе Program. Везде svet.Event1 поменяем его на TrafficLight.Event1, а svet.Event2 поменяем его на TrafficLight.Event2.

От статических событий можно отписаться в любом месте проекта.

Нам нужно, чтобы пешеход перешел дорогу и ушел, то есть не реагировал на светофор. То есть сразу после перехода улицы, в методе Go в классе Pedestrian нужно отписаться от событий связанных со светофором:

Нам нужно, чтобы водитель пересек перекресток и уехал, то есть не реагировал на светофор. То есть сразу после пересечения перекрестка, в методе Ride в классе Driver нужно отписаться от событий связанных со светофором:

Результат:

Пример 2

Проект «Автостоянка»

Классы: Car (машина), Parking (стоянка)- генерируются два события, Sequrity (охранник)-обработчик события , Police (полиция) обработчики двух событий и Program (тестирующий)

В классе Parking возникает два статических события:

  1. Событие NotPlaces. Возникает, когда на стоянке нет мест. Делегат NotPlacesEventHandler. На событие подписываются классы Sequrity и Police. Охранник закрывает стоянку. Полицейский включает видеонаблюдение.
  2. Событие SignalTriggered. Сработала сигнализация на стоянке. Событие возникает случайно. Делегат SignalTriggeredEventHandler (int k). Параметр k счетчик срабатываний. На событие подписывается класс Police. Полицейский приезжает на стоянку, после каждого срабатывания.

Отработка 1: возникло только событие NotPlaces.

Отработка 2: возникло событие NotPlaces и 3 раза возникло событие SignalTriggered.

Класс Car

Поле: номер машины

Свойство для чтения поля номер машины

Конструктор с параметром.

Класс Sequrity (охранник)

Поле: имя

Свойства для чтения поля имя.

Конструктор с параметрoм.

Обработчик события NotPlaces:

Класс Police (полиция)

Поле: имя

Свойствo для чтения поля имя.

Конструктор с параметрами.

Обработчик события NotPlaces:

Обработчик события SignalTriggered:

Класс Parking (стоянка)

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

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

Поля: адрес стоянки, количество мест, List < Car > - список машин, логическая переменная: есть ли места на стоянке, счетчик срабатываний сигнализации.

Свойство для чтения поля – есть ли места.

Конструктор с параметрами.

Метод, в котором возникает событие NotPlaces и событие SignalTriggered

Класс Program (тестирующий)

Создадим объекты трех классов: parking, sequrityMan, polisMan

Подпишемся на события.

На событие NotPlaces подпишем объекты sequrityMan и polisMan

На событие SignalTriggered подпишем объект polisMan

Так как события статические, то применяем их не объекту, а к классу.

В цикле, пока у объекта parking значение логического поля= true (места есть), выполняем:

Пример 3

Лямбда выражения

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

Из коллекции класса Employee выбираются и выводятся на экран участники проекта старше 16 лет., но моложе 46 лет.

В коллекции класса Employee находим и выводятся на экран самого старшего участника.

Назад Вперед Содержание