• 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开发中很重要的一种技巧

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

  • 相关阅读:
    .NET应用架构设计—表模块模式与事务脚本模式的代码编写
    .NET应用架构设计—重新认识分层架构(现代企业级应用分层架构核心设计要素)
    .NET应用架构设计—面向对象分析与设计四色原型模式(彩色建模、领域无关模型)(概念版)
    .NET应用架构设计—服务端开发多线程使用小结(多线程使用常识)
    .NET系列文章——近一年文章分类整理,方便各位博友们查询学习
    .NET应用架构设计—面向查询的领域驱动设计实践(调整传统三层架构,外加维护型的业务开关)
    .NET应用架构设计—面向查询服务的参数化查询设计(分解业务点,单独配置各自的数据查询契约)
    .NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)
    .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(三)
    .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(二)
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/4693270.html
Copyright © 2020-2023  润新知