美文网首页
中介者模式(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