iOS设计模式 - 观察者

简介:

iOS设计模式 - 观察者

 

原理图

 

说明

1. cocoa框架本身实现了观察者模式(通知中心以及KVO)

2. 本人所写的例子,实现了通知中心,其特殊的地方在于,不用移除订阅了通知的对象

 

源码

https://github.com/YouXianMing/iOS-Design-Patterns


//
//  SubscriptionServiceCenter.h
//  ObserverPattern
//
//  Created by YouXianMing on 15/7/29.
//  Copyright (c) 2015年 YouXianMing. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "SubscriptionServiceCenterProtocol.h"

/**
 *  订阅服务中心(实现了系统的通知中心业务逻辑)
 *
 *  = 注意 = 没有考虑发送通知的时候,同步与异步的问题
 *
 */
@interface SubscriptionServiceCenter : NSObject

/**
 *  创建订阅号
 *
 *  @param subscriptionNumber 订阅号码
 */
+ (void)createSubscriptionNumber:(NSString *)subscriptionNumber;

/**
 *  移除订阅号(参与到该订阅号码的所有客户不会再收到订阅信息)
 *
 *  @param subscriptionNumber 订阅号码
 */
+ (void)removeSubscriptionNumber:(NSString *)subscriptionNumber;

/**
 *  将指定客户从指定订阅号上移除掉
 *
 *  @param customer           客户对象
 *  @param subscriptionNumber 订阅号码
 */
+ (void)removeCustomer:(id <SubscriptionServiceCenterProtocol>)customer fromSubscriptionNumber:(NSString *)subscriptionNumber;

/**
 *  通知签订了订阅号码的对象
 *
 *  @param message            信息对象
 *  @param subscriptionNumber 订阅号码
 */
+ (void)sendMessage:(id)message toSubscriptionNumber:(NSString *)subscriptionNumber;

/**
 *  客户订阅指定的订阅号
 *
 *  @param customer           客户对象
 *  @param subscriptionNumber 订阅号码
 */
+ (void)addCustomer:(id <SubscriptionServiceCenterProtocol>)customer withSubscriptionNumber:(NSString *)subscriptionNumber;

@end


//
//  SubscriptionServiceCenter.m
//  ObserverPattern
//
//  Created by YouXianMing on 15/7/29.
//  Copyright (c) 2015年 YouXianMing. All rights reserved.
//

#import "SubscriptionServiceCenter.h"

static  NSMutableDictionary  *_subscriptionNumberDictionary = nil;

@implementation SubscriptionServiceCenter

#pragma mark - 初始化
+ (void)initialize {
    
    if (self == [SubscriptionServiceCenter class]) {
        
        _subscriptionNumberDictionary = [NSMutableDictionary dictionary];
    }
}

+ (void)createSubscriptionNumber:(NSString *)subscriptionNumber {

    NSParameterAssert(subscriptionNumber);
    
    NSHashTable *hashTable = [self existSubscriptionNumber:subscriptionNumber];
    
    if (hashTable == nil) {
        
        hashTable = [NSHashTable weakObjectsHashTable];
        [_subscriptionNumberDictionary setObject:hashTable forKey:subscriptionNumber];
    }
}

+ (void)removeSubscriptionNumber:(NSString *)subscriptionNumber {

    NSParameterAssert(subscriptionNumber);
    
    if ([self existSubscriptionNumber:subscriptionNumber]) {
        
        [_subscriptionNumberDictionary removeObjectForKey:subscriptionNumber];
    }
}

+ (void)removeCustomer:(id <SubscriptionServiceCenterProtocol>)customer fromSubscriptionNumber:(NSString *)subscriptionNumber {

    NSParameterAssert(subscriptionNumber);
    
    NSHashTable *hashTable = [self existSubscriptionNumber:subscriptionNumber];
    
    if (hashTable && customer) {
        [hashTable removeObject:customer];
    }
}

+ (void)sendMessage:(id)message toSubscriptionNumber:(NSString *)subscriptionNumber {
    
    NSParameterAssert(subscriptionNumber);
    
    NSHashTable *hashTable = [self existSubscriptionNumber:subscriptionNumber];
    
    if (hashTable) {
        
        NSEnumerator *enumerator = [hashTable objectEnumerator];
        
        id <SubscriptionServiceCenterProtocol> customer = nil;
        while (customer = [enumerator nextObject]) {
        
            if ([customer respondsToSelector:@selector(subscriptionMessage:subscriptionNumber:)]) {
                [customer subscriptionMessage:message subscriptionNumber:subscriptionNumber];
            }
        }
    }
}

+ (void)addCustomer:(id)customer withSubscriptionNumber:(NSString *)subscriptionNumber {

    NSParameterAssert(customer);
    NSParameterAssert(subscriptionNumber);
    
    NSHashTable *hashTable = [self existSubscriptionNumber:subscriptionNumber];
    [hashTable addObject:customer];
}


#pragma mark - 私有方法
+ (NSHashTable *)existSubscriptionNumber:(NSString *)subscriptionNumber {
    
    return [_subscriptionNumberDictionary objectForKey:subscriptionNumber];
}

@end


//
//  SubscriptionServiceCenterProtocol.h
//  ObserverPattern
//
//  Created by YouXianMing on 15/7/29.
//  Copyright (c) 2015年 YouXianMing. All rights reserved.
//

#import <Foundation/Foundation.h>

@protocol SubscriptionServiceCenterProtocol <NSObject>

/**
 *  接收到的订阅信息
 *
 *  @param message            订阅信息
 *  @param subscriptionNumber 订阅编号
 */
- (void)subscriptionMessage:(id)message subscriptionNumber:(NSString *)subscriptionNumber;

@end

分析

让一个对象,遵循某种制定的协议(接口)来完成特定的功能,是cocoa开发中很重要的一种技巧

订阅以及针对订阅号发布信息的完整流程


目录
相关文章
|
7月前
|
设计模式 测试技术 iOS开发
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(1)
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(1)
232 0
|
7月前
|
设计模式 搜索推荐 iOS开发
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(7)
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(7)
503 1
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(7)
|
7月前
|
设计模式 API iOS开发
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(2)
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(2)
268 0
|
7月前
|
设计模式 API iOS开发
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(3)
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(3)
406 0
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(3)
|
7月前
|
设计模式 iOS开发
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(6)
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(6)
247 0
|
3月前
|
设计模式 算法 调度
行为型设计模式:模板设计模式/观察者设计模式/策略设计模式/责任链设计模式
行为型设计模式:模板设计模式/观察者设计模式/策略设计模式/责任链设计模式
30 0
|
3月前
|
设计模式
设计模式-观察者(发布订阅)模式
设计模式-观察者(发布订阅)模式
|
7月前
|
设计模式 iOS开发 UED
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(4)
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(4)
248 0
|
7月前
|
设计模式 iOS开发
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(5)
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(5)
241 0
|
11月前
|
设计模式 存储 大数据
大数据开发基础的设计模式的观察者
观察者模式是大数据开发基础的设计模式之一。它是一种行为型模式,用于定义对象之间的一对多依赖关系,当一个对象状态发生改变时,其所有依赖者都会收到通知并自动更新。
65 0