Медиатор – паттерн которые определяет внутри себя объект, в котором реализуется взаимодействие между некоторым количеством объектов. При этом эти объекты, могут даже не знать про существования друг друга, потому взаимодействий реализованых в медиаторе может быть огромное количество.
Когда использовать:
- Когда у вас есть некоторое количество объектов, и очень тяжело реализовать взаимодействие между ними. Яркий пример – умный дом. Есть неколько датчиков, и несколько устройств. К примеру, датчик температуры следит за тем какая на даный момент температура, а кондционер умеет охлаждать воздух. При чем кондиционер, не обязательно знает про существования датчика температуры. Есть центральный компьютер, который получает сигналы от каждого из устройств и понимает, что делать в том или ином случает
- Тяжело переиспользовать объект, так как он взаимодействует и коммуницирует с огромным количеством других объектов.
- Логика взаимодействия должна легко настраиваться и расширяться.
Собственно, пример медиатора даже писать безсмысленно, потому как это любой контроллер который мы используем во время нашей разработки. Посудите сами – на view есть очень много контролов, и все правила взаимодействия мы прописываем в контроллере. Элементарно.
И все же пример не будет лишним Давайте все же создадим пример который показывает создание аля умного дома.
Пускай у нас есть оборудование которое может взаимодействоать с нашим умным домом:
@class ASCentrallProcessor; @interface ASSmartHousePart : NSObject - (instancetype)initWithCore:(ASCentrallProcessor *)processor; - (void)numbersChanged; @end
@interface ASSmartHousePart ()
@property (nonatomic, strong) ASCentrallProcessor *processor;
@end
@implementation ASSmartHousePart
- (instancetype)initWithCore:(ASCentrallProcessor *)processor {
self = [super init];
if (self) {
_processor = processor;
}
return self;
}
- (void)numbersChanged {
[self.processor valueChanged:self];
}
@end
Теперь, создадим сердце нашего умного дома:
@class ASThermometer, ASConditioningSystem; @class ASSmartHousePart; @interface ASCentrallProcessor : NSObject @property (nonatomic, strong) ASThermometer *thermometer; @property (nonatomic, strong) ASConditioningSystem *condSystem; - (void)valueChanged:(ASSmartHousePart *)part; @end
@implementation ASCentrallProcessor
- (void)valueChanged:(ASSmartHousePart *)part {
NSLog(@"Value changed! We need to do smth!");
// detecting that changes are done by thermometer
if ([part isKindOfClass:[ASThermometer class]]) {
NSLog(@"Oh, the change is temperature");
[self.condSystem startCondition];
}
}
@end
Тут очень интересный момент – класс ASCentrallProcessor должен знать про существование ASSmartHousePart, собственно и ASSmartHousePart должен знать про существование ASCentrallProcessor. Если все сделать простым import – то проект не скомпилируется. Потому, в ASSmartHousePart.h мы добавили @class ASCentrallProcessor; для того чтобы Xcode знал что за объект будет использован, и при этом не импортил файл заголовков ASCentrallProcessor.
Заголовки же мы импортим в ASSmartHousePart.m.
Дальше в классе ASCentrallPart в методе valueChanged мы определяем с какой деталью и что произошло, чтобы адекватно среагировать. В нашем примере – изменение температуры приводит к тому что мы включаем кондиционер.
А вот, и код термометра и кондиционера:
@interface ASThermometer : ASSmartHousePart @property (nonatomic, readonly) NSInteger temperature; - (void)temperatureChanged:(NSInteger)temperature; @end
@interface ASThermometer ()
@property (nonatomic) NSInteger temperature;
@end
@implementation ASThermometer
- (void)temperatureChanged:(NSInteger)temperature {
self.temperature = temperature;
[self numbersChanged];
}
@end
@interface ASConditioningSystem : ASSmartHousePart - (void)startCondition; @end
@implementation ASConditioningSystem
- (void)startCondition {
NSLog(@"Conditioning...");
}
@end
Как видим в результате у нас есть два объекта, которые друг про друга не в курсе, и все таки они взаимодействуют друг с другом посредством нашего медиатора ASCentrallProcessor.
Код для тестинга:
ASCentrallProcessor *proccessor = [[ASCentrallProcessor alloc] init];
ASThermometer *therm = [[ASThermometer alloc] initWithCore:proccessor];
ASConditioningSystem *condSystem = [[ASConditioningSystem alloc] initWithCore:proccessor];
proccessor.condSystem = condSystem;
proccessor.thermometer = therm;
[therm temperatureChanged:45];
И конечно же лог:
2017-08-29 21:55:00.547 PatternsObjC[2786:97404] Value changed! We need to do smth! 2017-08-29 21:55:00.547 PatternsObjC[2786:97404] Oh, the change is temperature 2017-08-29 21:55:00.548 PatternsObjC[2786:97404] Conditioning...
Немає коментарів:
Дописати коментар