Медиатор – паттерн которые определяет внутри себя объект, в котором реализуется взаимодействие между некоторым количеством объектов. При этом эти объекты, могут даже не знать про существования друг друга, потому взаимодействий реализованых в медиаторе может быть огромное количество.
Когда использовать:
- Когда у вас есть некоторое количество объектов, и очень тяжело реализовать взаимодействие между ними. Яркий пример – умный дом. Есть неколько датчиков, и несколько устройств. К примеру, датчик температуры следит за тем какая на даный момент температура, а кондционер умеет охлаждать воздух. При чем кондиционер, не обязательно знает про существования датчика температуры. Есть центральный компьютер, который получает сигналы от каждого из устройств и понимает, что делать в том или ином случает
- Тяжело переиспользовать объект, так как он взаимодействует и коммуницирует с огромным количеством других объектов.
- Логика взаимодействия должна легко настраиваться и расширяться.
Собственно, пример медиатора даже писать безсмысленно, потому как это любой контроллер который мы используем во время нашей разработки. Посудите сами – на 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...
Немає коментарів:
Дописати коментар