Это довольно длинный ответ, но я сначала рассмотрю ваш пример, а затем перейду к некоторым общим советам.Имейте в виду, что весь код является псевдокодом, он не будет компилироваться без корректировки синтаксиса.
Прежде всего, ваша логическая структура не имеет смысла, поэтому вам может быть трудно точно определить, верна ли онаили нет.
Например, в реальном мире вы не обращаетесь к автомобилю, чтобы купить его, вы обращаетесь в магазин или службу, которая их продает.Вы обращаетесь только к автомобилю, чтобы управлять автомобилем, или используете другие функции , которые он предлагает .Автомобиль не назначает себе лицензию.Наконец, покупка - это процесс, который, как правило, является линейным (и может быть выражен методом без триггеров), если вы берете базовый пример продавца / покупателя.Поэтому, когда вы вызываете shop.BuyCar( sportsCar )
, вся логика покупки может быть вызвана из метода покупки.
Class Shop{
public Car BuyCar( carWithoutLicense ){
//Purchase logic
LicenseService.AssignLicense( carWithoutLicense ).
return carWithoutLicense.
}
}
//A person would call this method, no the car
Лучшим примером правильно использованного события будет один из индикаторов на передней панели автомобиля.потому что это там, чтобы уведомить водителя о чем-то, на что он / она может захотеть отреагировать.Например: контрольная лампа двигателя.
class Car {
Bool CheckEngingLightIsOn = false;
public void Ride( ... ){
if( enginge.faultDetected == true ){
TurnOnCheckEngineAlert( );
}
}
public void TurnOnCheckEngineAlert( ){
CheckEngingLightIsOn = true;
if( CheckEngineLightSwitch != null ){
CheckEngineLightSwitch.Invoke( ... )
}
}
}
class Driver {
public Driver( Car car ){
this.car = car;
if( driverState != Drunk ){
car.CheckEngineLightSwitch = TakeAction;
}
}
public Drive( ){
car.Ride( );
}
public void TakeAction( Car car, EventArgs e ){
//get out, open the hood, check the engine...
if( car.CheckEngingLightIsOn == true ){ "Light turned on
//Check Engine
}else{
//continue driving
}
}
}
Не углубляясь в абстракцию, обратите внимание на цепочку событий:
Driver
ведет машину и не беспокоится одругие вещи (например, контрольная лампочка двигателя) до тех пор, пока они не произойдут. - Если
Car
обнаруживает неисправность, включается контрольная лампочка двигателя и на этом событии (подписчики) появляются обработчики событий, которые автомобиль вызываетсобытие. - Событие происходит, но водитель должен быть подписан на него, чтобы заметить изменение.
- ТОЛЬКО если водитель подписан на это событие (в данном случае, если он не пьян), он будетпринять меры на основе этого события.
Этот пример принципиально отличается от вашего примера, поскольку:
- Во время вождения автомобиля водителю не нужно платитьВнимание, постоянно проверяйте свет двигателя (хотя он может это проверить).
- Это стандартный процесс проверки состояния двигателя автомобиля и представления его на лампочке двигателя.
- Водитель и Автомобиль влияют на дальнейшие действия друг друга, и эта логика неэффективна, если выражается линейно.
Другими словами, процесс покупки основан на камне (оплата, лицензия, передача товара) и пропускает важные шагине может быть пропущеноСам процесс движения автомобиля не стоит на камне, потому что ни автомобиль, ни водитель не знают, что произойдет в дороге.Водитель IE может доехать до места назначения без остановки (если неисправность не возникает или если он не замечает свет), или автомобиль может заставить водителя остановиться, когда он заметит, что загорается контрольная лампа двигателя (по сути, они оба управляют друг другом вв некотором смысле).
Несколько общих советов о вашем прецеденте
В вашем примере вы сделали довольно сложный прецедент (с неправильно размещенной логикой), который он будет выполнять, но будет структурно некорректным (а плохая логическая структура ведет к ошибкам человека при разработке дальнейшей логики).
Первое, на что вы должны обратить внимание, - это какая логика имеет отношение к каждому объекту.Представляет ли событие / метод в вашем объекте что-то, что ваш объект делает (то есть функциональность, которую объект выполняет сам) или что-то, что влияет на ваш объект , но сам объект ничего не делает впроцесс?Например: автомобиль «едет» самостоятельно (даже если водитель запускает этот процесс и все его параметры, такие как скорость или направление);присвоение лицензии автомобилю происходит полностью вне структуры автомобиля, и только для автомобиля выполняется изменение атрибута (лицензия).
Это различие важно, потому что только логика , выполняемая вашим объектом , имеет отношение к этому объекту, и, соответственно, любая логика, которая выполняется другим объектом и влияет только на ваш объект , является не имеет значения принадлежит где-то еще. Так что Buy
определенно не принадлежит автомобилю, а Ride (процесс перемещения) принадлежит автомобилю.
Во-вторых, ваши имена будут иметь большое значение, чтобы помочь вам понять эту тему. Методы представляют действия и должны называться так (Shop.BuyCar
, Car.Ride
, Driver.Drive
), события представляют триггеры реакции (Car.CheckEngineLightSwitch
), а обработчики событий представляют реакции на действие (реакция по-прежнему является действием, поэтому никаких специальных имен не требуется, но вы можете указать имя, чтобы провести различие между действием и реакцией).