一、中介者模式
中介者,顾名思义,即一个处理各种交互集中化操作的角色。面向对象的设计思想鼓励把行为分散到不同的对象中,但是,这种行为的分散可能在一定程度上增大对象之间的关联,增大了系统的耦合度,为后期的维护和扩展带来不便。中介者模式定义了一个集中的场所,对象间的交互可以在一个中介者对象中集中处理,其他对象不必彼此交互,这样就减少了对象之间的关联。
定义:用一个对象来封装一系列对象的交互方式。中介者使得对象不需要显式地相互引用,从而使其达到松散耦合,而且可以独立地改变他们之间的交互。
Mediator为抽象的中介者,它定义了与抽象Colleague交互的一般行为,ConcreteMediator为ConcreteColleague定义了更加具体的行为,通过子类化中介者(Mediator),把各种Colleague交互行为应用到相同或者不同的colleague类型。Colleague的实例有一个中介者(Mediator)实例的引用,同时中介者的实例知道参与这个组织的每个对象。每一个ConcreteColleague只知道自己的交互行为,不知道其他的ConcreteColleague的行为,但是它们都知道ConcreteMediator对象。如果应用中只需要一个中介者,有时可以省去抽象的Mediator。
使用中介者模式的情形:
- 对象之间的交互定义明确但却非常复杂,导致对象之间彼此依赖且难以理解;
- 对象引用了许多其他对象并与之传递消息,导致对象难以复用;
- 想要定制一个分布在多个类中的逻辑或行为,同时又不想生成太多的子类。
二、iOS应用中的视图跳转/迁移的方法
在做iOS应用中难免遇到多个视图之间的转换或迁移,常用的方法有三种:
1、从另一个视图控制器把视图添加到当前的视图控制器中,作为子视图。
但是,这种方法有一个缺点,如果在添加子视图之前不把前一个视图删除的话,整个栈上的子视图会越来越多,最终使得栈中存在许多无用的子视图并且难于管理。在应用程序有许多视图时,不建议使用此方法。
2、通过使用导航控制器(UINavigationController)实现
首先,UINavigationController实例被一个根控制器初始化,根控制器提供自己的视图作为UINavigationController的第一个视图。
然后,如果需要跳转到另一个视图,视图的所有者就把它的控制器压入UINavigationController的栈中。
最后,由UINavigationController处理视图迁移的全部细节,如新视图迁移的转场动画等。
UINavigationController管理其内部的视图控制器栈,当前位于栈顶的视图控制器会显示在屏幕上,当需要返回到上一个视图时,将当前控制器弹出,然后下一个控制器的视图将被显示。
3
、通过让第一个视图控制器使用另一个视图控制器来显示模式视图,实现视图的跳转/迁移
这种方法使视图的迁移直接用视图控制器来管理,而不涉及到其它视图控制器的个别视图。其流程很简洁:每次只显示一个视图控制器,需要切换的时候,从一个视图控制器切换到另一个视图控制器。
假设有这样一个应用程序,它有三个视图控制器(如下图所示),每个控制器有自己的按钮,当用户点击按钮时,该按钮的控制器立即触发操作并处理视图的转换。为了能进行视图的迁移,每个控制器必须持有其它控制器的实例。视图的迁移可以通过显示模式视图或通过UINavigationController的实例协调处理。但是,想象一下, 如果后续有更多的视图控制器添加进来,这样结构的程序势必难以维护。
一个比较好的解决办法是把视图迁移的流程逻辑放到一个集中的对象中处理。该对象在应用中充当协调员或中介者来协调视图流程,而且应用中的视图迁移应该只由中介者决定。为此,我们引入一个新的控制器:CoordinatingController。所有的按钮对象都由该控制器持有,其它视图控制器不持有按钮对象。
CoordinatingController.h
#import "CanvasViewController.h"
#import "PaletteViewController.h"
#import "ThumbnailViewController.h"
@interface CoordintingController : NSObject
{
@private
CanvasViewController *canvasViewController_;
UIViewController *activeViewController_;
}
@property (readonly, nonatomic) UIViewController *activeViewController;
@property (readonly, nonatomic) CanvasViewController *canvasViewController;
+(CoordinatingController *) sharedInstance;
-(IBAction) requestViewChangeByObject : (id) object;
@end
CoordinatingController.m
#import "CoordinatingController.h"
@implementation CoordinatingController
@synthesize activeViewController = activeViewController_;
@synthesize canvasViewController = canvasViewController_;
//单例实现略
-(IBAction) requestViewChangeByObject:(id)object
{
if([object isKindOfClass : [UIBarButtonItem class])
{
switch([UIBarButtonItem*) object tag])
{
case kButtonTagOpenPaletteView:
{
// 加载PaletteViewController
PaletteViewController *pc = [[[PaletteViewController alloc] init] autorelease];
// 视图迁移
[canvasViewController_ presentModalViewController:pc animated:YES];
// 设置activeViewController为PaletteViewController
activeViewController_ = pc;
}
break;
case kButtonTagOpenThumbnailView:
{
...
}
break;
default: // 对于其它类型的标签,只是回到主视图canvasViewController
{
[canvasViewController_ dismissModalViewControllerAnimated:YES];
// 设置activeViewController为canvasViewController
activeViewController_ =canvasViewController;
}
break;
}
}
else
{
[canvasViewController_ dismissModalViewControllerAnimated:YES];
activeViewController_ =canvasViewController_;
}
}
@end