博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS设计模式——中介者模式
阅读量:6322 次
发布时间:2019-06-22

本文共 4719 字,大约阅读时间需要 15 分钟。

hot3.png

何为中介者模式?

    面向对象的设计鼓励把行为分散到不同对象中,这种分散可能导致对象之间的相互关联。在最糟糕的情况下,所有对象都彼此了解并相互操作。

    虽然把行为分散到不同对象增强了可复用性,但是增加的相互关联又减少了获得的益处。增加的关联使得对象很难或不能在不依赖其他对象的情况下工作。应用程序的整体行为可能难以进行任何重大修改,因为行为分布于许多对象。于是结果可能是创建越来越多的子类,以支持应用程序中的任何新行为。

    中介者模式:用一个对象来封装一系列对象的交互方式。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

何时使用中介者模式?

    @:对象间的交互虽定义明确然而非常复杂,导致一组对象彼此依赖而且难以理解。

    @:因为对象引用了许多其他对象并与其通讯,导致对象难以复用。

    @:想要定制一个分布在多个类中的逻辑或行为,又不想生成太多的子类。

中介者模式的应用实例:

    要是飞行员都争抢着起飞或降落机场而没有交通管制,会出现不可估量的危险。为了避免这种情况,飞行员就需要知道彼此的意图与位置。下面就如何知道彼此的位置来阐述中介者模式的应用。如下图所示,表示它们之间的关系。

235906_em42_1792456.png

    抽象的AbstractRadarMediator定义了用于同Plane交互的一般行为。ConcreteRadarMediator为Plane定义了更加具体的行为,因此可以子类化AbstractRadarMediator,把各种Plane交互算法应用到相同或不同的Plane类型。如果应用程序只需要一个中介者,有时抽象的Mediator可以省略。

    Plane的实例有一个Mediator实例的引用,同时AbstractRadarMediator的实例知道参与的每个对象。Plane的代码如下:

#import 
@class AbstractRadarMediator;// import "AbstractRadarMediator.h",不能这样写,否则会出现相互导入,导致错误提示,头文件找不到@interface Plane : NSObject@property (nonatomic, assign) float distance; //距离机场的距离@property (nonatomic, assign) float otherPlaneDistance; //其他飞机的位置@property (nonatomic, strong) AbstractRadarMediator *radarMediator; //保持雷达中介者的引用- (void)noticeLocation;@end
#import "Plane.h"@implementation Plane- (void)noticeLocation {    NSLog(@"通知其他飞机自己的位置");}@end

    Plane类中的noticeLocation方法的具体由其子类来进行扩充,通过这种方式可以定义多种行为。PlaneA与PlaneB的代码如下:

#import "Plane.h"@interface PlaneA : Plane- (void)noticeLocation; //重写该方法@end
#import "PlaneA.h"#import "AbstractRadarMediator.h"@implementation PlaneA- (void)noticeLocation {    [self.radarMediator noticeLocationToPlaneBWithDistance:self.distance];}@end
#import "Plane.h"@interface PlaneB : Plane- (void)noticeLocation; // 重写该方法@end
#import "PlaneB.h"#import "AbstractRadarMediator.h"@implementation PlaneB- (void)noticeLocation {    [self.radarMediator noticeLocationToPlaneAWithDistance:self.distance];}@end

    在这里我们可以看到noticeLocation的实现,通过中介者的方式向另外一个对象传递消息,这样做的好处就是使各对象不需要显式地相互引用,从而使其松耦合,而且可以独立地改变它们之间的交互。在AbstractRadarMediator定义同Plane对象交互的一般行为,代码如下:

#import 
#import "Plane.h"@interface AbstractRadarMediator : NSObject@property (nonatomic, strong) Plane *planeA;@property (nonatomic, strong) Plane *planeB;- (instancetype)initWithPlaneA:(Plane *)planeA planeB:(Plane *)planeB;- (void)noticeLocationToPlaneAWithDistance:(float)distance;- (void)noticeLocationToPlaneBWithDistance:(float)distance;@end
#import "AbstractRadarMediator.h"@implementation AbstractRadarMediator- (instancetype)initWithPlaneA:(Plane *)planeA planeB:(Plane *)planeB {    self = [super init];    if (self) {        _planeA = planeA;        _planeB = planeB;    }    return self;}- (void)noticeLocationToPlaneAWithDistance:(float)distance {    NSLog(@"由子类来实现");}- (void)noticeLocationToPlaneBWithDistance:(float)distance {    NSLog(@"由子类来实现");}@end

    在这里定义了noticeLocationToPlaneAWithDistance:(float)distance与noticeLocationToPlaneBWithDistance两种交互方式,但具体怎么交互,则由其相应的子类来完成,这样就更加灵活,方便为Plane对象提供各种交互算法。ConcreteRadarMediator类中的代码如下:

#import "AbstractRadarMediator.h"@interface ConcreteRadarMediator : AbstractRadarMediator// 重写这两个方法- (void)noticeLocationToPlaneAWithDistance:(float)distance;- (void)noticeLocationToPlaneBWithDistance:(float)distance;@end
#import "ConcreteRadarMediator.h"@implementation ConcreteRadarMediator- (void)noticeLocationToPlaneAWithDistance:(float)distance {    self.planeA.otherPlaneDistance = distance;}- (void)noticeLocationToPlaneBWithDistance:(float)distance {    self.planeB.otherPlaneDistance = distance;}@end

    到现在为止,上面已经介绍完中介者模式了,下面我们看下在客户端怎么使用中介者模式以及中介者模式带给我们的便利性,代码如下:

#import "ViewController.h"#import "Plane.h"#import "PlaneA.h"#import "PlaneB.h"#import "AbstractRadarMediator.h"#import "ConcreteRadarMediator.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];        Plane *planeA = [[PlaneA alloc] init];    PlaneB *planeB = [[PlaneB alloc] init];    AbstractRadarMediator *radarMediator = [[ConcreteRadarMediator alloc] initWithPlaneA:planeA planeB:planeB];    planeA.radarMediator = radarMediator; //保持AbstractRadarMediator的引用    planeB.radarMediator = radarMediator;        planeA.distance = 800.0f;    planeB.distance = 1000.0f;        [planeA noticeLocation];    NSLog(@"飞机B收到A的位置通知:%f", planeB.otherPlaneDistance);        [planeB noticeLocation];    NSLog(@"飞机A收到B的位置通知:%f", planeA.otherPlaneDistance);    }- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}@end

    输出端的内如如下:

2015-09-01 09:44:42.236 MediatorPatter[12407:407240] 飞机B收到A的位置通知:800.0000002015-09-01 09:44:42.237 MediatorPatter[12407:407240] 飞机A收到B的位置通知:1000.000000

    在这里我们就可以看到,planeA与planeB两个对象之间没有相互的引用,但却实现了两个对象之间的通信,这样就减少了两者之间的关联,从而使其耦合松散,这正是使用中介者模式的便利性。

  Demo链接地址:

转载于:https://my.oschina.net/daguoshi/blog/499906

你可能感兴趣的文章
微信程序开发
查看>>
如何退出minicom【学习笔记】
查看>>
Sqlserver 数据库基本查询
查看>>
图书馆维护系统总结
查看>>
[hadoop源码阅读][5]-counter的使用和默认counter的含义
查看>>
SAP HUM 如何对一个HU做上架?
查看>>
LINUX系统中动态链接库的创建与使用{补充}
查看>>
三维视觉国际会议首度在中国举办
查看>>
达索系统入手XFlow开发商 强化3DEXPERIENCE平台的仿真能力
查看>>
Loadrunner 性能测试服务器监控指标
查看>>
自动化运维工具之ansible
查看>>
memcached的安装
查看>>
freebsd系统安装
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
Linux LTP 测试框架
查看>>
log4j 每次运行生成文件
查看>>
“经常加班”有误区
查看>>
jquery各种事件触发实例
查看>>
我的友情链接
查看>>