概要
说到设计模式,可能大多数程序员的脑海里第一时间飘过的是下面的一系列文字:单例模式、代理模式、观察者模式、工厂方法模式等等,以上几个是平时用得最多的也是大家耳熟能详的设计模式。当然,设计模式并不仅限于这几个,还有更多,诸如:适配器模式、组合模式、装饰模式、策略模式、命令模式、责任链模式、中介者模式等等,这些设计模式有的会很好的应用在项目中,也有的用到的概率很低。接下来,就介绍一下其中比较简单的一个 —— 中介者模式。
简介
<p>
何为中介者模式?
中介者模式是用一个对象来封装一组或者一系列对象的交互方式,使对象间的交互可以在一个中介者对象中处理,从而使各对象耦合松散,而且可以独立的改变它们之间的交互。中介者就好比站在十字路口的交通警察,如果改变十字路口的交通模式,只需要把新的交通策略给交通警察即可,而不是路上的所有车辆,这样才能更好的协调来自不同方向车辆。
中介者模式有什么用?
说到中介者模式的作用,其实从上述的定义中便可以知道其大体用处,无非是用来集中的管理一组对象的交互,从而降低各个对象间的耦合度。当一组对象彼此间的依赖程度较高,导致难以复用时,便可以采用该模式。中介者,在应用程序整个生命周期应该只有一个实例,否则将无法管理多个对象间的交互,所以要使用单例实现。
使用场景
有这样的一个需求,在一个根视图控制器中(暂且称之为rootVC),有三个button,点击不同的button都会跳到对应的视图控制器中,分别是firstVC、secondVC、thirdVC。也许你会说,直接在rootVC中写跳转不是更简单吗?在视图控制器数量很少的情况下,这样的确比较简单直接,但是当后期试图控制器数量增多时,你会发现rootVC中的代码量变得复杂难以维护,所以需要一个中介者来协调他们的之间交互,从而降低耦合度、提高代码的维护性。代码如下:
1、rootVC中的button点击方法:
- (IBAction)clickedFirstAction:(UIButton *)sender {
[self coordinateToDifferentControllerWith:sender.tag];
}
- (IBAction)clickedSecondAction:(UIButton *)sender {
[self coordinateToDifferentControllerWith:sender.tag];
}
- (IBAction)clickedThirdAction:(UIButton *)sender {
[self coordinateToDifferentControllerWith:sender.tag];
}
- (void)coordinateToDifferentControllerWith:(NSInteger)tag {
[[MediatorManager sharedManager] coordinateViewControllers:@(tag)];
}
2、中介者(MediatorManager)中要保持一个对rootVC的引用,.h文件代码如下:
#import <Foundation/Foundation.h>
@class ViewController, UIViewController;
typedef NS_ENUM(NSInteger, ButtonTag) {
ButtonTagFirstVC = 1,
ButtonTagSecondVC = 2,
ButtonTagThirdVC = 3,
};
@interface MediatorManager : NSObject
@property (nonatomic, strong, readonly) ViewController *rootVC;
@property (nonatomic, strong, readonly) UIViewController *activeVC;
+ (MediatorManager *)sharedManager;
- (void)coordinateViewControllers:(id)tagValue;
@end
3、MediatorManager的.m文件代码:
#import "MediatorManager.h"
#import "ViewController.h"
#import "FirstViewController.h"
#import "SecondViewController.h"
#import "ThirdViewController.h"
@implementation MediatorManager
+ (MediatorManager *)sharedManager {
static MediatorManager *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
- (void)coordinateViewControllers:(id)tagValue {
if ([tagValue isKindOfClass:[NSNumber class]]) {
switch ([tagValue integerValue]) {
case ButtonTagFirstVC:
{
FirstViewController *firstVC = [[FirstViewController alloc] init];
_activeVC = firstVC;
[self.rootVC.navigationController pushViewController:firstVC animated:YES];
}
break;
case ButtonTagSecondVC:
{
SecondViewController *secondVC = [[SecondViewController alloc] init];
_activeVC = secondVC;
[self.rootVC.navigationController pushViewController:secondVC animated:YES];
}
break;
case ButtonTagThirdVC:
{
ThirdViewController *thirdVC = [[ThirdViewController alloc] init];
_activeVC = thirdVC;
[self.rootVC.navigationController pushViewController:thirdVC animated:YES];
}
break;
default:
_activeVC = self.rootVC;
[self.rootVC.navigationController popViewControllerAnimated:YES];
break;
}
}
}
@end
注意:在coordinateViewControllers方法里,用的是switch语句来判断各个试图控制的跳转,此方法并不是很好,如果视图控制器的数量增多时,这样显然不好,采用策略模式会更好一些。至于策略模式,会在以后的文章中作介绍。