问题:
在软件的开发过程中,势必会碰到这样一种情况,多个类或多个子系统相互交互,而且交互很繁琐,导致每个类都必须知道他需要交互的类,这样它们的耦合会显得异常厉害。牵一发而动全身,
好了,既然问题提出来了,那有请我们这期的主角——中介者模式出场吧!
中介者模式
用一个中介者对象来封装一系列的对象交互。中介者使得各对象不需要显式地相互引用,从而使其松散耦合,而且可以独立地改变它们之间的交互。
例子(oc版):
#import
@interface DPMredViewController : UIViewController
@end
#import "DPMredViewController.h"
#import "DPMediator.h"
@interface DPMredViewController ()
@end
@implementation DPMredViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor redColor];
self.title = @"我是红色控制器";
[self setupUI];
}
- (void)setupUI{
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
button.backgroundColor = [UIColor blackColor];
button.frame = CGRectMake(self.view.bounds.size.width/2-30, self.view.bounds.size.height/2-30, 60, 60);
[button addTarget:self action:@selector(clickButton:) forControlEvents:UIControlEventTouchUpInside];
button.layer.cornerRadius = 30;
button.layer.masksToBounds = YES;
[button setTitle:@"下一个" forState:UIControlStateNormal];
[self.view addSubview:button];
}
- (void)clickButton:(UIButton *)sender{
[[DPMediator shareInstance] requestNextViewControllerWithType:greenVCType];
}
@end
#import
@interface DPMgreenViewController : UIViewController
@end
#import "DPMgreenViewController.h"
#import "DPMediator.h"
@interface DPMgreenViewController ()
@end
@implementation DPMgreenViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor greenColor];
self.title = @"我是绿色控制器";
[self setupUI];
}
- (void)setupUI{
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
button.backgroundColor = [UIColor blackColor];
button.frame = CGRectMake(self.view.bounds.size.width/2-30, self.view.bounds.size.height/2-30, 60, 60);
[button addTarget:self action:@selector(clickButton:) forControlEvents:UIControlEventTouchUpInside];
button.layer.cornerRadius = 30;
button.layer.masksToBounds = YES;
[button setTitle:@"下一个" forState:UIControlStateNormal];
[self.view addSubview:button];
}
- (void)clickButton:(UIButton *)sender{
[[DPMediator shareInstance] requestNextViewControllerWithType:blueVCType];
}
@end
#import
@interface DPMblueViewController : UIViewController
@end
#import "DPMblueViewController.h"
#import "DPMediator.h"
@interface DPMblueViewController ()
@end
@implementation DPMblueViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor blueColor];
self.title = @"我是蓝色控制器";
[self setupUI];
}
- (void)setupUI{
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
button.backgroundColor = [UIColor blackColor];
button.frame = CGRectMake(self.view.bounds.size.width/2-30, self.view.bounds.size.height/2-30, 60, 60);
[button addTarget:self action:@selector(clickButton:) forControlEvents:UIControlEventTouchUpInside];
button.layer.cornerRadius = 30;
button.layer.masksToBounds = YES;
[button setTitle:@"下一个" forState:UIControlStateNormal];
[self.view addSubview:button];
}
- (void)clickButton:(UIButton *)sender{
[[DPMediator shareInstance] requestNextViewControllerWithType:defaultVCType];
}
@end
#import
typedef NS_ENUM(NSInteger, VCType) {
defaultVCType,
redVCType,
greenVCType,
blueVCType
};
@interface DPMediator : NSObject
+ (DPMediator *)shareInstance;
- (void)requestNextViewControllerWithType:(VCType) vctype;
@end
#import "DPMediator.h"
#import "AppDelegate.h"
#import "DPMredViewController.h"
#import "DPMgreenViewController.h"
#import "DPMblueViewController.h"
@interface DPMediator()
@end
@implementation DPMediator
+ (DPMediator *)shareInstance{
static DPMediator * instance = nil;
static dispatch_once_t tokeOnce;
dispatch_once(&tokeOnce, ^{
instance = [[DPMediator alloc] init];
});
return instance;
}
- (void)requestNextViewControllerWithType:(VCType) vctype{
UIViewController * viewController = [UIApplication sharedApplication].keyWindow.rootViewController.childViewControllers.lastObject;
switch (vctype) {
case redVCType:
{
DPMredViewController * vc = [[DPMredViewController alloc] init];
[viewController.navigationController pushViewController:vc animated:YES];
}
break;
case greenVCType:
{
DPMgreenViewController * vc = [[DPMgreenViewController alloc] init];
[viewController.navigationController pushViewController:vc animated:YES];
}
break;
case blueVCType:
{
DPMblueViewController * vc = [[DPMblueViewController alloc] init];
[viewController.navigationController pushViewController:vc animated:YES];
}
break;
case defaultVCType:
{
[viewController.navigationController popToRootViewControllerAnimated:YES];
}
break;
default:
break;
}
}
@end
//开始使用
#import "DPMmainViewController.h"
#import "DPMediator.h"
#import "DPMediatorWithC++Show.h"
@interface DPMmainViewController ()
@end
@implementation DPMmainViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
// Do any additional setup after loading the view.
self.title = @"中介者模式";
[self setupUI];
}
- (void)setupUI{
UIButton * button1 = [UIButton buttonWithType:UIButtonTypeCustom];
[button1 setTitle:@"oc版" forState:UIControlStateNormal];
button1.frame = CGRectMake(30, 200, 60, 60);
button1.backgroundColor = [UIColor redColor];
button1.layer.cornerRadius = 30;
button1.layer.masksToBounds = YES;
[button1 addTarget:self action:@selector(clickOCButton:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button1];
UIButton * button2 = [UIButton buttonWithType:UIButtonTypeCustom];
[button2 setTitle:@"c++版" forState:UIControlStateNormal];
button2.frame = CGRectMake(self.view.bounds.size.width-30-60, 200, 60, 60);
button2.backgroundColor = [UIColor redColor];
button2.layer.cornerRadius = 30;
button2.layer.masksToBounds = YES;
[button2 addTarget:self action:@selector(clickCCButton:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button2];
}
- (void)clickOCButton:(UIButton *)sender{
[[DPMediator shareInstance] requestNextViewControllerWithType:redVCType];
}
@end
例子(C++版):
#include
#include
#include
using namespace std;
//抽象的同事类
class Colleage{
private:
string name;
string content;
public:
Colleage(string n = " "):name(n){};
void setName(string name){
this->name = name;
}
string getName(){
return this->name;
}
void setContent(string content){
this->content = content;
}
string getContent(){
return this->content;
}
virtual void talk() {};
};
// 具体的同事类:班长
class Monitor : public Colleage{
public:
Monitor(string n = ""): Colleage(n){};
virtual void talk(){
cout<<"大班长说:"< studentList;
virtual void addStudent(Colleage * student){
studentList.push_back(student);
}
virtual void notify(Colleage * student){};
virtual void chart(Colleage * student1, Colleage * student2) {};
};
//具体中介者QQ通讯平台
class QQMediator : public Mediator{
public:
virtual void notify(Colleage * student){
student->talk();
for (int i =0; italk();
}
}
}
virtual void chart(Colleage * student1, Colleage * student2){
student1->talk();
student2->talk();
}
};
//使用
- (void)clickCCButton:(UIButton *)sender{
QQMediator qq;
Monitor studentMonitor("Vincent");
TuanZhiShu studentTuanZhiShu("Robort");
StudentA studentA("Sam");
StudentB studentB("Tom");
cout<<"下面的班长发布一个通知的场景:"<
总结:
中介者模式很容易在系统中应用,也很容易在系统中误用。当系统出现了多对多交互复杂的对象群时,不要急于使用中介者模式,而要先反思你在系统上设计是否合理。
优点就是集中控制,减少了对象之间的耦合度。缺点就是太过于集中。