设计模式

原创 2016年08月31日 10:51:55

设计模式

设计模式是用来解决编程某些特定问题。

单例模式

什么时候使用单例模式?

在一个工程中,有一些类只需要一个实例变量,我们就可以将这些类设计成单例模式

单例模式的作用?

当一个类A被设计成单例模式时,由A构造出的实例对象之于其它类来讲为全局实例对象,即在每一个类中由A构造出的实例对象,都为相同对象

在OC中如何将一个类设计成单例模式?

  1. 在要被设计成单例的类的.h文件中声明一个构造单例方法,如:

    +(Student *)shareIntance;   
    
  2. 实现该方法

    static Student *st = nil;//声明一个静态实例对象
    +(Student *)shareIntance{
        if (st == nil) {
        st = [[Student alloc] init];
        }
        return st;
    }
    
    //为了防止通过 alloc 或 new 创建新的实例
    +(id)allocWithZone:(struct _NSZone *)zone{
        @synchronized(self){
            if (st == nil) {
          st = [[super allocWithZone:zone] init];
            }
        }
        return st;
    }
    //为了防止copy产生出新的对象,需要实现 NSCopying 协议
    -(id)copyWithZone:(NSZone *)zone{
    return self;
    }
    
    

观察者模式

什么是观察者模式?

在工程中,一些类去观察A类,当A类发生变化时,这些观察类就会收到消息,做出相应反应。

什么时候使用观察者模式?

当一个类需要发送消息给多个类的时候,就用观察者模式

观察者模式的作用?

一对多的发送消息

如何在OC中实现观察者模式?

OC中观察者模式的设计基础:KVC / KVO

KVC的由来:在iOS2.0之前,并没有属性来访问类中实例变量,那时候开发人员使用 键值编码 的方式来访问类中的实例变量,即 KVC方式。

使用KVC来访问类中实例变量:

Student *st = [[Student alloc] init];
//赋值
[st setValue:@"vincent" forKey:@"_name"];
[st setValue:@25 forKey:@"_age"];


//访问
NSString *name = [st valueForKey:@"_name"];
 NSNumber *age = [st valueForKey:@"_age"];

//键路径编码
Book *book = [Book new];
 //st.book = book;
//st.book.bookName = @"金品梅";

[st setValue:book forKeyPath:@"_book"];
[st setValue:@"金品梅" forKeyPath:@"_book._bookName"];

NSLog(@"%@",[book description]);

NSString *bookName = [st valueForKeyPath:@"_book._bookName"];


[st setValue:@"guangzhou" forKeyPath:@"_address"];
    NSLog(@"des = %@",[st description]);

KVO的由来:在编程过程中,我们经常需要判断目标是否发生改变,以便及时的做出对应的处理。此时苹果公司就提供一种策略,即OC运行时提供了kVO技术。其中KVO是基于KVC实现。

KVO的实现:
1. 注册成为观察者
2. 观察者定义KVO回调
3. 移除观察者
代码示例:

-(id)initWithStudent:(Student *)st{
    if (self = [super init]) {
        self.st = st;
        //1.注册观察者
        [self.st addObserver:self forKeyPath:@"_name" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:nil];
        [self.st addObserver:self forKeyPath:@"_age" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:nil];
        [self.st addObserver:self forKeyPath:@"_book._bookName" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:nil];

    }
    return self;
}
//注册KVO回调
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    if ([keyPath isEqualToString:@"_name"]) {
        NSLog(@"name change = %@",change);
    }
    if ([keyPath isEqualToString:@"_age"]) {
        NSLog(@"age change = %@",change);
    }
    if ([keyPath isEqualToString:@"_book._bookName"]) {
         NSLog(@"book change = %@",change);
    }
}
//移除观察者
-(void)dealloc{
    [self.st removeObserver:self forKeyPath:@"_name" context:nil];
    [self.st removeObserver:self forKeyPath:@"_age" context:nil];
    [self.st removeObserver:self forKeyPath:@"_book._bookName" context:nil];
}

通知

通过学习KVO,我们发现KVO是一种简单的观察者设计模式,涉及到两个对象,分别是观察者和被观察者。这种方式实质有很大局限性,那么OC的Foundation框架,在基于KVO的基础上又为开发者提供了新的一种观察者设计模式,即通知

通知是一种发送给一个或者多个观察者,用来通知其在程序中发生了某个事件的消息。它是一种程序中事件的发起者或者是处理者和其它想要知道该事件的对象的沟通的一种方式。消息的接受者,即观察响应改事件来变换自己的UI、行为或者状态。

在OC中,使用NSNotification类来表示一个通知。

 //初始化一个NSNotification类的实例对象
NSNotification *notification1 = [NSNotification notificationWithName:@"通知名称" object:self];
NSNotification *notification2 = [NSNotification notificationWithName:@"通知名称" object:self userInfo:@{@"content":@"jay is on living"}];

其中:

  1. name:表示通知名称,最好英文名,用来识别通知对象
  2. object:表示通知的发起人
  3. userInfo:表示通知的内容

    ——————————————————————————

在现实生活中,我们的邮件都需要由邮局发送给接收人。在OC中也一样,Foundation框架定义了一个单例类,通知中心NSNotificationCenter来统一发送通知的实例对象给观察者

 //通知中心 单例类,拿到通知中心的单例
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    //通知中心发送通知
  [center postNotification:notification1];

简便写法,通知中心直接发送通知

[center postNotificationName:<#(NSString *)#> object:<#(id)#>]

[center postNotificationName:<#(NSString )#> object:<#(id)#> userInfo:<#(NSDictionary )#>]

建立通知发送机制,步骤如下:

  1. 注册相关监听者,并实现监听收到通知时的方法
  2. 在需要的时候,被监听的对象去通知中心发送通知
  3. delloc方法中,移除通知

关键代码示例:

//到通知中心去让自己成为某个通知的监听对象
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationAction:) name:TeacherWithStudentNotification object:nil];

        //实现当前对象接收通知时的方法
        -(void)notificationAction:(NSNotification *)notification{
    NSLog(@"notification userinfo = %@",notification.userInfo);
    NSLog(@"上厕所");
    }
    //到main函数调用此方法,发送通知
    -(void)sendNoficaiton{
    [[NSNotificationCenter defaultCenter] postNotificationName:TeacherWithStudentNotification object:self userInfo:@{@"context":@"下课"}];
}

    //在delloc方法中移除通知
    -(void)dealloc{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:TeacherWithStudentNotification object:nil];
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

Android设计模式-MVC模式设计

我对开源的理解     首先,感谢Google 的开源系统,让我有了一份Android系统工程师的工作;第二,感谢开源系统,让我们以更加开放、自由的精神工作;第三,感谢工程师对知识和经验的共享,...
  • u014675538
  • u014675538
  • 2016年03月17日 17:15
  • 1396

【设计模式】HeadFirst设计模式(一):策略(Strategy)模式

1、概述 在软件开发的过程中,实现一个功能可能会使用很多种算法,一种比较常用的做法是把这些算法或者策略写在一个类中,一个算法写一个方法。当我们需要新增一个算法的时候,我们需要修改封装这些算法的类,并且...
  • u010800530
  • u010800530
  • 2015年04月19日 13:56
  • 1128

【设计模式】HeadFirst设计模式(三):装饰者(Decorator)模式

今天就来写一下装饰者模式,该软考了,也该实习了,感觉心态静不下来,设计模式都是一些简单的小例子,但是看了这么久连简单的了解还没有完全搞定,深感惭愧,还是要安静下来,书中才有颜如玉~ ~ ~不扯了,下边...
  • u010800530
  • u010800530
  • 2015年05月05日 09:22
  • 1399

程杰的大话设计模式

  • 2018年01月11日 14:10
  • 49B
  • 下载

JavaScript设计模式与开发实践

  • 2018年01月06日 00:17
  • 8.02MB
  • 下载

HeadFirst设计模式英文版

  • 2018年01月04日 21:07
  • 41.16MB
  • 下载

设计模式:基于C#的工程化实现及扩展 王翔

  • 2018年01月09日 23:05
  • 38.25MB
  • 下载

head first 设计模式

  • 2018年01月08日 22:17
  • 41.82MB
  • 下载

大话设计模式(带目录完整版)

  • 2018年01月07日 21:12
  • 64.19MB
  • 下载

大话设计模式带目录

  • 2018年01月07日 15:07
  • 69.82MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:设计模式
举报原因:
原因补充:

(最多只允许输入30个字)