美文网首页
中介者模式(Mediator Pattern)

中介者模式(Mediator Pattern)

作者: iOS_学渣 | 来源:发表于2019-11-27 09:57 被阅读0次
中介者模式:使用中介者模式来集中相关对象之间复杂的沟通和控制方式。

中介者模式是行为型模式之一。
这里中介者模式的定义已经描述得很清楚了,不同的对象,之间因为沟通和控制会导致复杂的交互逻辑,这样,对象过多,那么逻辑会一团乱麻。
而使用中介者模式会将这些逻辑集中在中介者中处理。

中介者模式

使用中介者模式之后

  1. 每个对象在状态发生改变时都会通知中介者。
  2. 每个对象都会对中介者的请求做出响应。

下面我们还是举个简单的栗子吧
设想一下,我们有一个计时器,每隔2秒会调起咖啡机加热咖啡(假设咖啡2秒后冷却)。
定时器每隔3秒调用热水器加热饮用水(假设热水3秒后冷却)。
咖啡开始煮的时候暂停计时,煮热后再开启计时器(每次加热减少2个量的水,咖啡水量为某个设定的值,最大水量为20)。
热水器开始加热时暂停计时,沸腾后再开启计时器(热水器每次加热减少1个量的水,水量为某个设定的值)。
咖啡每次加热都会导致浓度增加,因此当达到一定当浓度的时候会需要热水器注入一定的热水。

这是咖啡机和热水器的协议(Java为接口)

#import <Foundation/Foundation.h>
@class Mediator;

NS_ASSUME_NONNULL_BEGIN

@protocol MechineProtocol <NSObject>

-(void)startWithMediator:(Mediator *)mediator;

-(void)stopWithMediator:(Mediator *)mediator;

@end

NS_ASSUME_NONNULL_END

咖啡机的实现

#import "CoffieMechine.h"
#import "Mediator.h"
@interface CoffieMechine ()

@property (nonatomic ,strong)NSTimer * timer;
@end

static NSInteger const MINSIZEOFCUPS = 12;

@implementation CoffieMechine

-(void)startWithMediator:(Mediator *)mediator {
    
    NSLog(@"开始加热coffee...");
    [mediator timerStopWithTarget:self];
    //这里用一个定时器来模拟加热过程
    _timer = [NSTimer scheduledTimerWithTimeInterval:5 repeats:NO block:^(NSTimer * _Nonnull timer) {
        NSLog(@"加热coffee完成...");
        
        self.cupsOfWater -= 2;
        
        [mediator timerRestartWithTarget:self];
        //水量警告位
        if (self.cupsOfWater <= MINSIZEOFCUPS) {
            
            [mediator addWaterWithTarget:self];
        }
    }];
}

-(void)stopWithMediator:(Mediator *)mediator {
    
    [_timer invalidate];
    _timer = nil;
    
}

@end

热水器的实现

#import "WaterMechine.h"
#import "Mediator.h"

@interface WaterMechine()

@property (nonatomic ,strong)NSTimer * timer;
@end

static NSInteger const MINSIZEOFCUPS = 8;

@implementation WaterMechine

- (void)startWithMediator:(Mediator *)mediator {
    
    NSLog(@"开始加热water...");
    [mediator timerStopWithTarget:self];
    //这里用一个定时器来模拟加热过程
    _timer = [NSTimer scheduledTimerWithTimeInterval:5 repeats:NO block:^(NSTimer * _Nonnull timer) {
        
        NSLog(@"加热water完成...");
        [self removeWaterWithMediator:mediator cups:1];
        [mediator timerRestartWithTarget:self];
    }];
}

-(void)stopWithMediator:(Mediator *)mediator {
    
    [_timer invalidate];
    _timer = nil;
}

-(void)addWaterWithMediator:(Mediator *)mediator cups:(NSInteger)cups {
    
    self.cups += cups;
}

-(void)removeWaterWithMediator:(Mediator *)mediator cups:(NSInteger)cups {
    
    self.cups -=  cups;
    [self checkWaterWithMediator:mediator];
}

-(void)checkWaterWithMediator:(Mediator *)mediator {
    
    if (self.cups < MINSIZEOFCUPS) {
        
        [mediator addWaterWithTarget:self];
    }
}

@end

计时器的相关逻辑

#import "TimerMechine.h"
#import "Mediator.h"

@interface TimerMechine()

@property (nonatomic ,strong)NSMutableArray * targetArray;

@property (nonatomic ,strong)NSMutableArray * timerArray;

@property (nonatomic ,weak)Mediator * mediator;

@end

@implementation TimerMechine


-(NSMutableArray *)targetArray {
    
    if(!_targetArray) {
        
        _targetArray = [NSMutableArray array];
    }return _targetArray;
}

-(NSMutableArray *)timerArray {
    
    if (!_timerArray) {
        
        _timerArray = [NSMutableArray array];
    }return _timerArray;
}


-(void)createTimerWithMediator:(Mediator *)mediator interval:(NSTimeInterval)interval target:(id)target repeats:(BOOL)repeats{
    
    self.mediator = mediator;
    if (![self.targetArray containsObject:target]) {
        __weak __typeof__(self) weakSelf = self;
        NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:interval repeats:repeats block:^(NSTimer * _Nonnull timer) {
            
            [weakSelf.mediator timerRunWithTarget:target];
        }];
        [self.timerArray addObject:@{@(interval):timer}];
        [self.targetArray addObject:target];
    }
}


-(void)stopTimerWithTarget:(id)target {
    
    NSInteger index = [self.targetArray indexOfObject:target];
    NSTimer * timer = [[self.timerArray objectAtIndex:index] allValues][0];
    if (timer.fireDate != [NSDate distantFuture]) {
        [timer setFireDate:[NSDate distantFuture]];
    }
}


-(void)startTimerWithTarget:(id)target {
    
    if ([self.targetArray containsObject:target]) {
        
        NSInteger index = [self.targetArray indexOfObject:target];
        NSTimer * timer = [[self.timerArray objectAtIndex:index] allValues][0];
        NSTimeInterval interval = [[[self.timerArray objectAtIndex:index] allKeys][0] doubleValue];
        if (timer.fireDate != [NSDate distantPast]) {
            [timer setFireDate:[NSDate dateWithTimeIntervalSinceNow:interval]];
        }
    }
}

//在水位过低时应该允许关闭计时器保护机器
-(void)removeAllTarget {
    
    [self.targetArray removeAllObjects];
    
    [self.timerArray enumerateObjectsUsingBlock:^(NSDictionary *  _Nonnull temp, NSUInteger idx, BOOL * _Nonnull stop) {
        
        NSTimer * timer = [temp allValues][0];
        [timer invalidate];
        timer = nil;
    }];
    
    [self.timerArray removeAllObjects];
}

@end

中介者逻辑

#import "Mediator.h"

@interface Mediator ()

@property (nonatomic ,strong)TimerMechine * timeMechine;
@property (nonatomic ,strong)CoffieMechine * coffieMechie;
@property (nonatomic ,strong)WaterMechine * waterMechine;
@end

@implementation Mediator

-(instancetype)initWithTimeMechine:(TimerMechine *)timeMechine coffieMechine:(CoffieMechine *)coffieMechie waterMechine:(WaterMechine *)waterMechine {
    
    if (self = [super init]) {
        
        _timeMechine = timeMechine;
        _coffieMechie = coffieMechie;
        _waterMechine = waterMechine;
    }return self;
}

//调用暂停计时器
-(void)timerStopWithTarget:(nullable id)target {
    
    [_timeMechine stopTimerWithTarget:target];
    
}

//重新开始计时器
-(void)timerRestartWithTarget:(id)target {
    
    [_timeMechine startTimerWithTarget:target];
}

//计时器触发事件
-(void)timerRunWithTarget:(nullable id)target {
    
    id<MechineProtocol> mTarget = target;
    [mTarget startWithMediator:self];
}

//水位不足时加水
-(void)addWaterWithTarget:(id)target {
    
    if (target == _waterMechine) {
        
        NSLog(@"NO water");
    }else if (target == _coffieMechie) {
        
        NSInteger cups = _waterMechine.cups;
        
        if (cups > 5) {
            
            [_waterMechine removeWaterWithMediator:self cups:5];
            _coffieMechie.cupsOfWater += 5;
            return;
        }else {
            
            //停止烧水
            [_waterMechine stopWithMediator:self];
            [_waterMechine removeWaterWithMediator:self cups:cups];
            _coffieMechie.cupsOfWater += cups;
        }
        
        if (_coffieMechie.cupsOfWater <= 8) {
            
            [self stopAll];
        }
    }
}

//水位严重不足时停止所有机器
-(void)stopAll {

   [_timeMechine removeAllTarget];
   [_waterMechine stopWithMediator:self];
   [_coffieMechie stopWithMediator:self];
    NSLog(@"全部停止");
}

@end

正常调用

    _timeMechine = [[TimerMechine alloc] init];
    
    _coffieMechine = [[CoffieMechine alloc] init];
    _coffieMechine.cupsOfWater = 12;
    
    _waterMechine = [[WaterMechine alloc] init];
    _waterMechine.cups = 2;
    
    _mediator = [[Mediator alloc] initWithTimeMechine:_timeMechine coffieMechine:_coffieMechine waterMechine:_waterMechine];
    
    [_timeMechine createTimerWithMediator:_mediator interval:3 target:_coffieMechine repeats:YES];
    [_timeMechine createTimerWithMediator:_mediator interval:3 target:_waterMechine repeats:YES];

优点

1.通过对象彼此解耦,可以提高对象的复用性
2.通过控制逻辑集中,简化系统维护
3.简化对象之间消息的发送。减少消息的数量

缺点

如果设计不当,中介者本身可能会变得过于复杂

中介者往往被用来协调GUI组件。

相关文章

网友评论

      本文标题:中介者模式(Mediator Pattern)

      本文链接:https://www.haomeiwen.com/subject/eyqqwctx.html