中介者模式
中介者模式很好的詮釋了迪米特法則,任意兩個不相關的物件之間如果需要關聯,那麼需要通過第三個類來進行。中介者就是把一組物件進行封裝,遮蔽了類之間的互動細節,使不同的類直接不需要持有對方引用也可以進行訪問。
中介者Mediator會持有同事類(就是需要處理互動邏輯的物件)Colleague的引用,同時每個colleague也會持有Mediator一份引用。這樣colleague如果有任何和別的類互動的請求就會發給Mediator,對改組物件進行了解耦合。其實我們平時經常寫的檢視控制器本身就是一箇中介中,它來控制著不同物件之間的互動行為。
應用場景
物件間互動雖然定義明確然而非常複雜,導致一組物件彼此相互依賴而且難以理解;
因為物件引用了許多其他物件並與其通訊,導致物件難以複用;
想要定製一個分佈在多個類中的邏輯或行為,又不想生成太多子類。
中介者的優缺點
優點
Mediator出現減少了各個Colleague的耦合,使得可以獨立地改變和複用各個Colleague類和Mediator,由於把物件如何寫作進行了抽象,將中介者作為一個獨立的概念並將其封裝在一個物件中,這樣關注的物件就從物件各自本身的行為轉移到它們之間的互動上,也就是站在一個更巨集觀的角度去看待系統。
缺點
由於ConcreteMediator控制了集中化,於是就把互動複雜性變為了中介者的複雜性,這就使得中介者會變得比任何一個ConcreteColleague都複雜。
Demo
Colleague
#import <Foundation/Foundation.h> @class Mediator; @interface Colleague : NSObject @property (nonatomic, weak) Mediator* mediator; -(instancetype)initWithMediator:(Mediator *)mediator; -(void)notifyAnother; -(void)notified:(NSString *)message; @end #import "Colleague.h" #import "Mediator.h" @implementation Colleague -(instancetype)initWithMediator:(Mediator *)mediator { self = [super init]; if(self) { _mediator = mediator; } return self; } -(void)notified:(NSString *)message { NSLog(@"%@",message); } -(void)notifyAnother { [self.mediator notify:self]; } @end #import "Colleague.h" @interface ConcreteColleagueA : Colleague @end #import "ConcreteColleagueA.h" @implementation ConcreteColleagueA @end #import "Colleague.h" @interface ConcreteColleagueB : Colleague @end #import "ConcreteColleagueB.h" @implementation ConcreteColleagueB @end
在OC中為了避免引用迴圈,所以Colleague的Mediator物件修飾符用weak
Mediator
#import <Foundation/Foundation.h> #import "ConcreteColleagueA.h" #import "ConcreteColleagueB.h" @interface Mediator : NSObject @property (nonatomic ,strong) ConcreteColleagueA *colleagueA; @property (nonatomic ,strong) ConcreteColleagueB *colleagueB; -(void)notify:(NSObject *)obj; @end #import "Mediator.h" @implementation Mediator -(id)init { self = [super init]; if(self) { } return self; } -(void)notify:(NSObject *)obj { if (obj == self.colleagueA) { [self.colleagueB notified:@"B notified"]; } else { [self.colleagueA notified:@"A notified"]; } } @end
客戶端
Mediator *mediator = [[Mediator alloc] init]; ConcreteColleagueA *colleagueA = [[ConcreteColleagueA alloc] initWithMediator:mediator]; ConcreteColleagueB *colleagueB = [[ConcreteColleagueB alloc] initWithMediator:mediator]; mediator.colleagueA = colleagueA; mediator.colleagueB = colleagueB; [colleagueA notifyAnother]; [colleagueB notifyAnother];
2015-07-26 16:48:42.508 Mediator[3888:1799182] B notified 2015-07-26 16:48:42.509 Mediator[3888:1799182] A notified