何為中介者模式?
物件導向的設計鼓勵把行為分散到不同對象中,這種分散可能導致對象之間的相互關聯。在最糟糕的情況下,所有對象都彼此瞭解並相互操作。
雖然把行為分散到不同對象增強了可複用性,但是增加的相互關聯又減少了獲得的益處。增加的關聯使得對象很難或不能在不依賴其他對象的情況下工作。應用程式的整體行為可能難以進行任何重大修改,因為行為分佈於許多個物件。於是結果可能是建立越來越多的子類,以支援應用程式中的任何新行為。
中介者模式:用一個對象來封裝一系列對象的互動方式。中介者使各對象不需要顯式地相互引用,從而使其耦合鬆散,而且可以獨立地改變它們之間的互動。
何時使用中介者模式?
1.對象間的互動雖定義明確然而非常複雜,導致一組對象彼此依賴而且難以理解。
2.因為對象引用了許多其他對象並與其通訊,導致對象難以複用。
3.想要定製一個分布在多個類中的邏輯或行為,又不想產生太多的子類。
中介者模式的實現樣本:
下面先給出類結構圖,再做簡單解釋。
中介者模式很容易在系統中引用,但是也比較容易誤用。所以當系統出現了“多對多”互動複雜的對象群時,不要急於使用中介者模式,而要先反思系統在設計上是不是合理。
下面我們來說一說,中介者模式的優缺點。中介者的優點首先是Mediator的出現減少了各個Colleague的耦合,使得可以獨立地改變和複用各個Colleague類和Mediator。其次,由於把對象如何協作進行了抽象,將中介作為一個獨立的概念並將其封裝在一個對象中,這樣關注的對象就從對象各自本身的行為轉移到它們之間的互動上來,也就是站在一個更宏觀的角度去看待系統。
相對來說,缺點也很明顯。由於ConcreteMediator控制了集中化,於是就把互動複雜性變為了中介者的複雜性,這就使得中介者會變得比任何一個ConcreteColleage都複雜。所以一旦ConcreteMediator崩潰,那麼整個系統都會受到影響。
還是那句老話,世上沒有銀彈,合適的就是最好的!
下面給大家簡單展示一下具體實現。
注意:本文所有代碼均在ARC環境下編譯通過。
Mediator類介面
複製代碼 代碼如下:
#import <Foundation/Foundation.h>
@class Colleague;
@interface Mediator :NSObject
-(void)Send:(NSString*)message
:(Colleague*)colleague;
@end
Mediator類實現
複製代碼 代碼如下:
#import "Mediator.h"
@implementation Mediator
-(void)Send:(NSString *)message :(Colleague *)colleague{
return;
}
@end
Colleague類介面
複製代碼 代碼如下:
#import <Foundation/Foundation.h>
@class Mediator;
@interface Colleague :NSObject{
Mediator *myMediator;
}
-(Colleague*)MyInit:(Mediator*)mediator;
@end
Colleague類實現
複製代碼 代碼如下:
#import "Colleague.h"
@implementation Colleague
-(Colleague*)MyInit:(Mediator *)mediator{
if (self == [super init]) {
myMediator = mediator;
}
return self;
}
@end
ConcreteMediator類介面
複製代碼 代碼如下:
#import "Mediator.h"
@class ConcreteColleague1;
@class ConcreteColleague2;
@interface ConcreteMediator :Mediator
@property ConcreteColleague1*colleague1;
@property ConcreteColleague2*colleague2;
@end
ConcreteMediator類實現
複製代碼 代碼如下:
#import "ConcreteMediator.h"
#import "ConcreteColleague1.h"
#import "ConcreteColleague2.h"
#import "Colleague.h"
@implementation ConcreteMediator
@synthesize colleague1;
@synthesize colleague2;
-(void)Send:(NSString *)message :(Colleague *)colleague{
if ([colleague isKindOfClass:[ConcreteColleague1 class]]) {
[colleague2 Notify:message];
}
else {
[colleague1 Notify:message];
}
}
@end
ConcreteColleague1類介面
複製代碼 代碼如下:
#import "Colleague.h"
@class Mediator;
@interface ConcreteColleague1 :Colleague
-(ConcreteColleague1*)MyInit:(Mediator*)mediator;
-(void)Send:(NSString*)message;
-(void)Notify:(NSString*)message;
@end
ConcreteColleague1類實現
複製代碼 代碼如下:
#import "ConcreteColleague1.h"
#import "Mediator.h"
@implementation ConcreteColleague1
-(ConcreteColleague1*)MyInit:(Mediator*)mediator{
if (self == [super init]) {
myMediator = mediator;
}
return self;
}
-(void)Send:(NSString *)message{
[myMediator Send:message :self];
}
-(void)Notify:(NSString *)message{
NSLog(@"ConcreteColleague1 got message:%@", message);
}
@end
ConcreteColleague2類介面
複製代碼 代碼如下:
#import "Colleague.h"
@class Mediator;
@interface ConcreteColleague2 :Colleague
-(ConcreteColleague2*)MyInit:(Mediator*)mediator;
-(void)Send:(NSString*)message;
-(void)Notify:(NSString*)message;
@end
ConcreteColleague2類實現
#import "ConcreteColleague2.h"
#import "Mediator.h"
@implementation ConcreteColleague2
-(ConcreteColleague2*)MyInit:(Mediator*)mediator{
if (self == [super init]) {
myMediator = mediator;
}
return self;
}
-(void)Send:(NSString *)message{
[myMediator Send:message :self];
}
-(void)Notify:(NSString *)message{
NSLog(@"ConcreteColleague2 got message:%@", message);
}
@end
Main方法調用
複製代碼 代碼如下:
#import <Foundation/Foundation.h>
#import "ConcreteMediator.h"
#import "ConcreteColleague1.h"
#import "ConcreteColleague2.h"
int main(int argc,const char * argv[])
{
@autoreleasepool{
ConcreteMediator *m = [[ConcreteMediator alloc]init];
ConcreteColleague1 *c1 = [[ConcreteColleague1 alloc]MyInit:m];
ConcreteColleague2 *c2 = [[ConcreteColleague2 alloc]MyInit:m];
[m setColleague1:c1];
[m setColleague2:c2];
[c1 Send:@"Good morning"];
[c2 Send:@"Good afternoon"];
}
return 0;
}
完工!