设计模式深入浅出(六)对象去耦——中介者

对象去耦

我们的程序中,一般不会只有一个类,而通常是有多个类互相合作。

既然提到互相合作,那么类对象间的耦合性是不可避免的。但是我们需要控制耦合的程度,将类的实现及关系控制在可以灵活改变的程度。

当我们发现我们的代码,牵一发而动全身的时候,有两个可能:
1. 类封装的不合理,不符合职责单一原则
2. 类之间的组织方式不合理,需要对象去耦。而这,就需要对象去耦模式。

对象去耦主要包括两种模式:中介者,观察者。

今天,我们先看中介者模式。

一个例子

试想一下,我们要实现如下的APP功能,都是如何做的?

这个APP有一个colorView,用来显示对应的color button点选的颜色。同时,colorLabel会显示当前选中颜色的中文名称。并且,我们有一个Disable按钮,它会将所有的颜色选择按钮禁用,并将colorView设置为cleanColor。

这里写图片描述

代码该怎么写?so easy。

//
// ViewController.m
// MediatorDemo
//
// Created by ShiTeng on 17/10/16.
// Copyright © 2017年 Eren. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
@property (strong, nonatomic) IBOutlet UIView *colorView;

@property (strong, nonatomic) IBOutlet UILabel *colorLabel;
@property (strong, nonatomic) IBOutlet UIButton *redButton;
@property (strong, nonatomic) IBOutlet UIButton *greenButton;
@property (strong, nonatomic) IBOutlet UIButton *orangeButton;
@property (strong, nonatomic) IBOutlet UIButton *yellowButton;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)redClick:(id)sender {
    self.colorView.backgroundColor = [UIColor redColor];
    self.colorLabel.text = @"红色";
}

- (IBAction)greenClick:(id)sender {
    self.colorView.backgroundColor = [UIColor greenColor];
    self.colorLabel.text = @"绿色";
}
- (IBAction)orangeClick:(id)sender {
    self.colorView.backgroundColor = [UIColor orangeColor];
    self.colorLabel.text = @"橘红色";
}
- (IBAction)yellowClick:(id)sender {
    self.colorView.backgroundColor = [UIColor yellowColor];
    self.colorLabel.text = @"黄色";
}
- (IBAction)disableClick:(id)sender {
    self.colorView.backgroundColor = [UIColor clearColor];
    self.redButton.userInteractionEnabled = NO;
    self.greenButton.userInteractionEnabled = NO;
    self.orangeButton.userInteractionEnabled = NO;
    self.yellowButton.userInteractionEnabled = NO;
    self.colorLabel.text = @"未知";

}

@end

好,让我们思考这样一个问题:毫无疑问,在我们的colorButton,colorView,colorLabel,disableButton之间,是有关联的。比如,当我点击colorButton,colorView需要变色,同时colorLabel需要显示对应的中文名字。

那么,colorButton, colorView, colorLable之前有相互引用吗?没有。

从代码设计角度来讲,很神奇是不是,几个相互关联的对象之间竟然没有相互的引用。也就是说,colorButton根本不知道colorView,colorLabe的存在。colorButton只需要专注于相应click事件就好。

这是怎么实现的呢?从代码里很容易看出,我们的colorButton在接收click事件时,并没有将事件直接通知给colorView和colorLabel,而是将click事件通知给了当前的UIViewController对象。同理,disableButton也是这么做的。

- (IBAction)orangeClick:(id)sender {
    self.colorView.backgroundColor = [UIColor orangeColor];
    self.colorLabel.text = @"橘红色";
}

- (IBAction)disableClick:(id)sender {
    self.colorView.backgroundColor = [UIColor clearColor];
    self.redButton.userInteractionEnabled = NO;
    self.greenButton.userInteractionEnabled = NO;
    self.orangeButton.userInteractionEnabled = NO;
    self.yellowButton.userInteractionEnabled = NO;
    self.colorLabel.text = @"未知";

}

将这种关系画一下示意图:
这里写图片描述

所有的对象都没有耦合,它们仅是将自己的事件告诉UIViewController,UIViewController会调用对应的View来响应变化。UIIViewController在这里充当了各个view的中介(Mediator)的作用。

OK,这就是中介者模式。中介者模式通过将所有的事件转发到中介者上,由中介者进行消息的转发与调用相关的对象进行处理,这样使本来相关的各个对象彻底解耦

中介者模式

用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

一般的,我们将相互作用的对象(例子中的colorButton,colorView,Label等)称为“同事(colleague)”,而负责协调同事们共同协作的中间人(UIViewController),我们称之为中介者(Mediator)。

UML图为:
这里写图片描述

这里有几个要点:

  • Mediator知道所有的Colleague对象
  • Colleague对象不知道对方Colleague,它仅是将自身的事件传到Mediator,由Mediator负责调度对应的Colleague。

优缺点

优点:

  • 中介者的优点很明显,将相关的对象之间做了彻底地解耦。
  • 它使得控制更集中化

缺点:

  • 中介者模式虽然将相关联的对象彻底的解耦,但是实质上是将对象间的关联由“对象间”转移到“中介者”内部。这就导致中介者本身的耦合性相当高,而且会成为一个无所不知,无所不能的超级类。

如何简化“中介者”,是中介者模式的一个难点。

相关的,iOS的组件化编程,也是利用了中介者模式的思想。将APP切分成若干子工程,而这些工程,则是由中介者工程所连接,协作。

相关文章
相关标签/搜索