中介者模式
在一些很多对象之间会存在一定的交互,例如像即时聊天软件中的语言视频通话,这种就有很多的界面变化、如呼入中、呼出中、通话中、视频中、免提,等等多种UI状态,点击相应的按钮,界面其它的UI元素也会随之改变。我们就可以使用中介者模式,进行统一管理、统一调度。同样的在iOSAPP中我们的控制器界面也同样可以使用这种管理模式,例如我们的界面控制单元有启动页、登录页、主页面另外还可以有广告页,我们就可以使用一个主控制器来统一管理分配改展示什么页面。
中介者模式类图:
图中我们可以通过RootViewController来统一调度页面的展示在APP上。
UniversalApp模型的实现
- (void)loadLaunchViewController
{
[self addChildViewController:_launchVc];
}
- (void)loadLoginViewController
{
[self addChildViewController:_loginVc];
}
- (void)loadMainViewController
{
[self addChildViewController:_mainVc];
}
本节工程示例
观察者模式
当一个对象的状态和信息发生改变的时候,其它许多和它相关的对象也需要作出相应的变化的场景时,我们就可以使用观察者模式。就像订阅报纸一样,我需要报纸就先订阅,然后新的期刊到来时,就会收到新来的报纸。观察者模式
观察者模式类图:
SubjectCenter的实现
static SubjectCenter *center = nil;
+ (instancetype)sharedInstance{
static dispatch_once_t once;
dispatch_once(&once, ^{
center = [[SubjectCenter alloc] init];
});
return center;
}
- (instancetype)init
{
self = [super init];
if (self) {
_bookCenter = [NSMutableDictionary dictionary];
}
return self;
}
// 创建书刊订阅号
- (void)creatNumber:(NSString *)subNumber {
NSMutableArray *arr = [self existNumber:subNumber];
if (arr == nil) {
arr = [NSMutableArray array];
[_bookCenter setObject:arr forKey:subNumber];
}
}
// 移除订阅号
- (void)removeNumber:(NSString *)subNumber {
NSMutableArray *arr = [self existNumber:subNumber];
if (arr == nil) {
arr = [NSMutableArray array];
[_bookCenter removeObjectForKey:subNumber];
}
}
// 添加用户
- (void)addUser:(id )user wihtNumber:(NSString *)userNumber {
NSMutableArray *arr = [self existNumber:userNumber];
[arr addObject:user];
}
// 移除用户
- (void)removeUser:(id )user withNumber:(NSString *)userNumber {
NSMutableArray *arr = [self existNumber:userNumber];
[arr removeObject:user];
}
// 发送消息
- (void)sendMessage:(id)message withSubNumber:(NSString *)userNumber {
NSMutableArray *arr = [self existNumber:userNumber];
if (arr) {
for (id observe in arr) {
if ([observe respondsToSelector:@selector(subMessage:withSubNumber:)]) {
[observe subMessage:message withSubNumber:userNumber];
}
}
}
}
- (NSMutableArray *)existNumber:(NSString *)subStringNumber {
return [_bookCenter objectForKey:subStringNumber];
}
在iOS的系统中,我们常用的有通知模式和键值编码的形式,前者以广播形式发送特定的消息,而后者则是被观察的对象直接向观察者发送通知,绑定特定对象属性的值。
本节工程示例
访问者模式
在一些对象结构中,如果要对其中的对象进行很多不相关操作的时候,又不想让这些操作迫使这些对象的类混乱,我们便可以将这些操作集中起来,定义在一个访问者类中,并在访问者中定义的操作使用它。对这些对象进行依赖一些的具体类型的操作还有添加新的操作都可以使用这种访问者模式。也就是在不改变各元素类的前提下定义作用于这些元素的新操作。例如我们的开发者有安卓开发和iOS开发者,分别进行OA签到和Git上传代码,就可以使用访问者模式,去相关服务器进行操作而不改变服务器。访问者模式用尽可能的修改,可以把组合结构与其他的访问者类中的相关算法分离。
访问者模式类图:
实例代码中实现了iOS开发者访问OA服务器的签到和Git服务器的下载代码功能。
其中GitWebsite的实现
- (void)acceptDeveloper:(Developer *)developer
{
[self doSomething];
}
- (void)doSomething
{
NSLog(@"下载iOS代码");
}
本节工程示例
策略模式
在开发中我们往往根据不同情况使用不同的算法,一般会使用if-else或者switch-case条件语句来进行判断,如果算法过多的话往往比较复杂并且难以维护。这个时候将不同的算法一个个的封装起来,并使他们可以相互替换,就可以避免了多重条件的判断,并且拥有良好的扩展性。例如我们出去旅游,有多种旅行方式,我们把每种出行方式封装成单独的一个对象来实现。
策略模式类图:
TravelStrategy根据不同的算法接口,实现不同的出行方式。
TravelStrategy的实现
- (id)initWithTravelStrategy:(TravelStrategy *)strategy
{
self = [super init];
if (self) {
_strategy = strategy;
}
return self;
}
- (void)travel
{
[_strategy travel];
}
本节工程示例
责任链模式
在一些有多个对象可以处理请求,而处理只有在运行的时候才能确定的场景下,包括向一组对象发出请求,又不想显示的指定处理请求的特定处理程序的场景下,我们就可以使用责任链模式进行程序设计。这使得多个对象都有机会处理请求,也避免了发送者和接收者之间发生耦合。这种模式将这些对象连成一条链,将请求沿着这条链传递,直到有一个对象处理为止。例如,在公司进行财务审批,组长能审批不大于1000的金额,超过的话交给经理来处理,但超过100000的话,只能交给老板来审批了。
责任链模式类图:
MemberModel定义了统一的接口,它的操作可以通过递归传达到借点的每一处。
其中ApplyHander的实现
- (void)handleApplyMoneyCount:(NSInteger)moneyCount
{
[self.nextHander handleApplyMoneyCount:moneyCount];
}
GroupLeaderHander的实现
- (void)handleApplyMoneyCount:(NSInteger)moneyCount
{
if (moneyCount <= 1000) {
NSLog(@"组长通过了审批");
}else{
[super handleApplyMoneyCount:moneyCount];
}
}
ManagerHander的实现
- (void)handleApplyMoneyCount:(NSInteger)moneyCount
{
if (moneyCount <= 10000) {
NSLog(@"经历通过了审批");
}else{
[super handleApplyMoneyCount:moneyCount];
}
}
BossManager的实现
- (void)handleApplyMoneyCount:(NSInteger)moneyCount
{
NSLog(@"老板通过了审批");
}
客户端的调用
NSInteger moneyCount = 99999;
GroupLeaderHander *groupLeader = [[GroupLeaderHander alloc] init];
ManagerHander *manager = [[ManagerHander alloc] init];
BossManager *boss = [[BossManager alloc] init];
groupLeader.nextHander = manager;
manager.nextHander = boss;
[groupLeader handleApplyMoneyCount:moneyCount];
本节工程示例