中介模式
中介模式的英文是Mediator Design Pattern。中介模式定义了一个单独的(中介)对象,来封装一组对象之间的交互。将这组对象之间的交互委派给与中介对象交互,来避免对象之间的直接交互。
中介模式的设计思想跟中间层很像,通过引入中介这个中间层,将一组对象之间的交互关系(或者说依赖关系)从多对多(网状关系)转换为一对多(星状关系)。原来一个对象要跟n个对象交互,现在只需要跟一个中介对象交互,从而最小化对象之间的交互关系,降低了代码的复杂度,提高了代码的可读性和可维护性。
右边的交互图是利用中介模式对左边交互关系优化之后的结果,从图中可以很直观地看出,右边的交互关系更加清晰、简洁。
提到中介模式,有一个比较经典的例子不得不说,那就是航空管制。
为了让飞机在飞行的时候互不干扰,每架飞机都需要知道其他飞机每时每刻的位置,这就需要时刻跟其他飞机通信。飞机通信形成的通信网络就会无比复杂。这个时候,通过引入”塔台“这样一个中介,让每架飞机只跟塔台来通信,发送自己的位置给塔台,由塔台来负责每架飞机的航线调度。这样就大大简化了通信网络。
假设有一个比较复杂的页面,页面中有很多控件,比如登录按钮、注册按钮、用户名文本框、密码文本框、确认密码文本框等。当对某个控件进行操作的时候,其他控件会做出相应的反应,比如,点击去登录按钮,登录相关的控件就会显示在页面中。点击去注册按钮,注册相关的控件就会显示在页面中。
按照通常习惯的UI界面开发方式,代码实现如下。控件和控件之间互相操作、互相依赖。
@interface DMMediatorDesignPatternViewController : UIViewController
@end
@interface DMMediatorDesignPatternViewController ()
@property (nonatomic, strong) UITextField *mUserNameTextField;
@property (nonatomic, strong) UITextField *mPasswordTextField;
@property (nonatomic, strong) UITextField *mRepeatedPasswordTextField;
// 去登录
@property (nonatomic, strong) UIButton *mGoLoginBtn;
// 去注册
@property (nonatomic, strong) UIButton *mGoRegisterBtn;
@property (nonatomic, strong) UIButton *mLoginBtn;
@property (nonatomic, strong) UIButton *mRegisterBtn;
@end
@implementation DMMediatorDesignPatternViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.title = @"中介模式";
// 省略布局
}
- (void)goLoginBtnClicked:(id)sender
{
// 显示登录相关控件
}
- (void)goRegisterBtnClicked:(id)sender
{
// 显示注册相关控件
}
- (void)loginBtnClicked:(id)sender
{
// 获取用户名、密码
// 校验数据...
// 做业务处理
}
- (void)registerBtnClicked:(id)sender
{
// 获取用户名、密码、重复密码
// 校验数据...
// 做业务处理
}
#pragma mark - getter and setter
- (UITextField *)mUserNameTextField
{
if (_mUserNameTextField == nil) {
_mUserNameTextField = [[UITextField alloc] init];
_mUserNameTextField.placeholder = @"输入用户名";
}
return _mUserNameTextField;
}
- (UITextField *)mPasswordTextField
{
if (_mPasswordTextField == nil) {
_mPasswordTextField = [[UITextField alloc] init];
_mPasswordTextField.placeholder = @"输入密码";
}
return _mPasswordTextField;
}
- (UITextField *)mRepeatedPasswordTextField
{
if (_mRepeatedPasswordTextField == nil) {
_mRepeatedPasswordTextField = [[UITextField alloc] init];
_mRepeatedPasswordTextField.placeholder = @"输入确认密码";
}
return _mRepeatedPasswordTextField;
}
- (UIButton *)mGoLoginBtn
{
if (_mGoLoginBtn == nil) {
_mGoLoginBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[_mGoLoginBtn setTitle:@"去登录" forState:UIControlStateNormal];
[_mGoLoginBtn addTarget:self action:@selector(goLoginBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
}
return _mGoLoginBtn;
}
- (UIButton *)mGoRegisterBtn
{
if (_mGoRegisterBtn == nil) {
_mGoRegisterBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[_mGoRegisterBtn setTitle:@"去注册" forState:UIControlStateNormal];
[_mGoRegisterBtn addTarget:self action:@selector(goRegisterBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
}
return _mGoRegisterBtn;
}
- (UIButton *)mLoginBtn
{
if (_mLoginBtn == nil) {
_mLoginBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[_mLoginBtn setTitle:@"登录" forState:UIControlStateNormal];
[_mLoginBtn addTarget:self action:@selector(loginBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
}
return _mLoginBtn;
}
- (UIButton *)mRegisterBtn
{
if (_mRegisterBtn == nil) {
_mRegisterBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[_mRegisterBtn setTitle:@"注册" forState:UIControlStateNormal];
[_mRegisterBtn addTarget:self action:@selector(registerBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
}
return _mRegisterBtn;
}
@end
按照中介模式,将上面的代码重构。在新的代码实现中,各个控件只跟中介对象交互,中介对象负责所有的业务逻辑的处理。
@protocol DMMediator <NSObject>
- (void)handleEventWithView:(UIView *)view eventString:(NSString *)eventStr;
@end
@interface DMLandingPage : NSObject <DMMediator>
- (void)setUserNameTextField:(UITextField *)textField;
- (void)setPasswordTextField:(UITextField *)textField;
- (void)setRepeatedPasswordTextField:(UITextField *)textField;
- (void)setGoLoginButton:(UIButton *)btn;
- (void)setGoRegisterButton:(UIButton *)btn;
- (void)setLoginButton:(UIButton *)btn;
- (void)setRegisterButton:(UIButton *)btn;
@end
@interface DMLandingPage ()
@property (nonatomic, strong) UITextField *mUserNameTextField;
@property (nonatomic, strong) UITextField *mPasswordTextField;
@property (nonatomic, strong) UITextField *mRepeatedPasswordTextField;
// 去登录
@property (nonatomic, strong) UIButton *mGoLoginBtn;
// 去注册
@property (nonatomic, strong) UIButton *mGoRegisterBtn;
@property (nonatomic, strong) UIButton *mLoginBtn;
@property (nonatomic, strong) UIButton *mRegisterBtn;
@end
@implementation DMLandingPage
- (void)setUserNameTextField:(UITextField *)textField
{
self.mUserNameTextField = textField;
}
- (void)setPasswordTextField:(UITextField *)textField
{
self.mPasswordTextField = textField;
}
- (void)setRepeatedPasswordTextField:(UITextField *)textField
{
self.mRepeatedPasswordTextField = textField;
}
- (void)setGoLoginButton:(UIButton *)btn
{
self.mGoLoginBtn = btn;
}
- (void)setGoRegisterButton:(UIButton *)btn
{
self.mGoRegisterBtn = btn;
}
- (void)setLoginButton:(UIButton *)btn
{
self.mLoginBtn = btn;
}
- (void)setRegisterButton:(UIButton *)btn
{
self.mRegisterBtn = btn;
}
- (void)handleEventWithView:(UIView *)view eventString:(NSString *)eventStr
{
if (self.mGoRegisterBtn == view) {
self.mUserNameTextField.hidden = NO;
self.mPasswordTextField.hidden = NO;
self.mRepeatedPasswordTextField.hidden = NO;
self.mGoRegisterBtn.hidden = YES;
self.mGoLoginBtn.hidden = NO;
// ...省略其它逻辑
} else if (self.mGoLoginBtn == view) {
self.mUserNameTextField.hidden = NO;
self.mPasswordTextField.hidden = NO;
self.mRepeatedPasswordTextField.hidden = NO;
self.mGoRegisterBtn.hidden = NO;
self.mGoLoginBtn.hidden = YES;
// ...省略其它逻辑
} else if (self.mLoginBtn == view) {
NSString *userName = self.mUserNameTextField.text;
NSString *password = self.mPasswordTextField.text;
// 校验数据
// 业务处理
} else if (self.mRegisterBtn == view) {
NSString *userName = self.mUserNameTextField.text;
NSString *password = self.mPasswordTextField.text;
NSString *repeatedPassword = self.mRepeatedPasswordTextField.text;
// 校验数据
// 业务处理
}
}
@end
@interface DMMediatorDesignPatternViewController : UIViewController
@end
@interface DMMediatorDesignPatternViewController ()
@property (nonatomic, strong) UITextField *mUserNameTextField;
@property (nonatomic, strong) UITextField *mPasswordTextField;
@property (nonatomic, strong) UITextField *mRepeatedPasswordTextField;
// 去登录
@property (nonatomic, strong) UIButton *mGoLoginBtn;
// 去注册
@property (nonatomic, strong) UIButton *mGoRegisterBtn;
@property (nonatomic, strong) UIButton *mLoginBtn;
@property (nonatomic, strong) UIButton *mRegisterBtn;
@property (nonatomic, strong) DMLandingPage *mLandingPage;
@end
@implementation DMMediatorDesignPatternViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.title = @"中介模式";
[self.mLandingPage setUserNameTextField:self.mUserNameTextField];
[self.mLandingPage setPasswordTextField:self.mPasswordTextField];
[self.mLandingPage setRepeatedPasswordTextField:self.mRepeatedPasswordTextField];
[self.mLandingPage setGoLoginButton:self.mGoLoginBtn];
[self.mLandingPage setGoRegisterButton:self.mGoRegisterBtn];
[self.mLandingPage setLoginButton:self.mLoginBtn];
[self.mLandingPage setRegisterButton:self.mRegisterBtn];
// 省略布局
}
- (void)goLoginBtnClicked:(id)sender
{
[self.mLandingPage handleEventWithView:self.mGoLoginBtn eventString:@"Click"];
}
- (void)goRegisterBtnClicked:(id)sender
{
[self.mLandingPage handleEventWithView:self.mGoRegisterBtn eventString:@"Click"];
}
- (void)loginBtnClicked:(id)sender
{
[self.mLandingPage handleEventWithView:self.mLoginBtn eventString:@"Click"];
}
- (void)registerBtnClicked:(id)sender
{
[self.mLandingPage handleEventWithView:self.mRegisterBtn eventString:@"Click"];
}
#pragma mark - getter and setter
- (UITextField *)mUserNameTextField
{
if (_mUserNameTextField == nil) {
_mUserNameTextField = [[UITextField alloc] init];
_mUserNameTextField.placeholder = @"输入用户名";
}
return _mUserNameTextField;
}
- (UITextField *)mPasswordTextField
{
if (_mPasswordTextField == nil) {
_mPasswordTextField = [[UITextField alloc] init];
_mPasswordTextField.placeholder = @"输入密码";
}
return _mPasswordTextField;
}
- (UITextField *)mRepeatedPasswordTextField
{
if (_mRepeatedPasswordTextField == nil) {
_mRepeatedPasswordTextField = [[UITextField alloc] init];
_mRepeatedPasswordTextField.placeholder = @"输入确认密码";
}
return _mRepeatedPasswordTextField;
}
- (UIButton *)mGoLoginBtn
{
if (_mGoLoginBtn == nil) {
_mGoLoginBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[_mGoLoginBtn setTitle:@"去登录" forState:UIControlStateNormal];
[_mGoLoginBtn addTarget:self action:@selector(goLoginBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
}
return _mGoLoginBtn;
}
- (UIButton *)mGoRegisterBtn
{
if (_mGoRegisterBtn == nil) {
_mGoRegisterBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[_mGoRegisterBtn setTitle:@"去注册" forState:UIControlStateNormal];
[_mGoRegisterBtn addTarget:self action:@selector(goRegisterBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
}
return _mGoRegisterBtn;
}
- (UIButton *)mLoginBtn
{
if (_mLoginBtn == nil) {
_mLoginBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[_mLoginBtn setTitle:@"登录" forState:UIControlStateNormal];
[_mLoginBtn addTarget:self action:@selector(loginBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
}
return _mLoginBtn;
}
- (UIButton *)mRegisterBtn
{
if (_mRegisterBtn == nil) {
_mRegisterBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[_mRegisterBtn setTitle:@"注册" forState:UIControlStateNormal];
[_mRegisterBtn addTarget:self action:@selector(registerBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
}
return _mRegisterBtn;
}
- (DMLandingPage *)mLandingPage
{
if (_mLandingPage == nil) {
_mLandingPage = [[DMLandingPage alloc] init];
}
return _mLandingPage;
}
@end
原本业务逻辑会分散在各个控件中,现在都集中到了中介类中。
网友评论