前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面向对象设计的设计模式(四):单例模式

面向对象设计的设计模式(四):单例模式

作者头像
用户2932962
发布2019-01-09 10:48:57
1K0
发布2019-01-09 10:48:57
举报

定义

单例模式(Singleton Pattern):单例模式确保某一个类只有一个实例,并提供一个访问它的全剧访问点。

适用场景

系统只需要一个实例对象,客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。比较典型的例子是音乐播放器,日志系统类等等。

成员与类图

成员

单例模式只有一个成员,就是单例类。因为只有一个成员,所以该设计模式的类图比较简单:

模式类图

单例模式类图

一般来说单例类会给外部提供一个获取单例对象的方法,内部会用静态对象的方式保存这个对象。

代码示例

场景概述

在这里我们创建一个简单的打印日至或上报日至的日至管理单例。

场景分析

在创建单例时,除了要保证提供唯一实例对象以外,还需注意多线程的问题。下面用代码来看一下。

代码实现

创建单例类 LogManager

//================== LogManager.h ==================
@interface LogManager : NSObject

+(instancetype)sharedInstance;

- (void)printLog:(NSString *)logMessage;

- (void)uploadLog:(NSString *)logMessage;

@end



//================== LogManager.m ==================
@implementation LogManager

static LogManager* _sharedInstance = nil;

+(instancetype)sharedInstance
{
    static dispatch_once_t onceToken ;
    dispatch_once(&onceToken, ^{
        _sharedInstance = [[super allocWithZone:NULL] init] ;
    }) ;
    return _sharedInstance ;
}

+(id)allocWithZone:(struct _NSZone *)zone
{
    return [LogManager sharedInstance] ;
}

-(id)copyWithZone:(struct _NSZone *)zone
{
    return [LogManager sharedInstance];
}

-(id)mutableCopyWithZone:(NSZone *)zone
{
    return [LogManager sharedInstance];
}

- (void)printLog:(NSString *)logMessage{
    //print logMessage
}

- (void)uploadLog:(NSString *)logMessage{
    //upload logMessage
}

@end

从上面的代码中可以看到:

  • sharedInstance方法是向外部提供的获取唯一的实例对象的方法,也是该类中的其他可以创建对象的方法的都调用的方法。在这个方法内部使用了dispatch_once函数来避免多线程访问导致创建多个实例的情况。
  • 为了在alloc init出初始化方法可以返回同一个实例对象,在allocWithZone:方法里面仍然调用了sharedInstance方法。
  • 而且为了在copymutableCopy方法也可以返回同一个实例对象,在copyWithZone:mutableCopyWithZone也是调用了sharedInstance方法。

下面分别用这些接口来验证一下实例的唯一性:

//================== Using by client ==================

//alloc&init
LogManager *manager0 = [[LogManager alloc] init];

//sharedInstance
LogManager *manager1 = [LogManager sharedInstance];

//copy
LogManager *manager2 = [manager0 copy];

//mutableCopy
LogManager *manager3 = [manager1 mutableCopy];

NSLog(@"\nalloc&init:     %p\nsharedInstance: %p\ncopy:           %p\nmutableCopy:    %p",manager0,manager1,manager2,manager3);

我们看一下打印出来的四个指针所指向对象的地址:

alloc&init:     0x60000000f7e0
sharedInstance: 0x60000000f7e0
copy:           0x60000000f7e0
mutableCopy:    0x60000000f7e0

可以看出打印出来的地址都相同,说明都是同一对象,证明了实现方法的正确性。

下面我们看一下该例子对应的 UML类图,可以更直观地看一下各个成员之间的关系:

代码对应的类图

单例模式代码示例类图

优点

  • 提供了对唯一实例的受控访问。因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它。
  • 因为该类在系统内存中只存在一个对象,所以可以节约系统资源。

缺点

  • 由于单例模式中没有抽象层,因此单例类很难进行扩展。
  • 对于有垃圾回收系统的语言(Java,C#)来说,如果对象长时间不被利用,则可能会被回收。那么如果这个单例持有一些数据的话,在回收后重新实例化时就不复存在了。

iOS SDK 和 JDK 中的应用

  • 在Objective-C语言中使用单例模式的类有NSUserDefaults(key-value持久化)和UIApplication类(代表应用程序,可以处理一些点击事件等)。
  • 在JDK中使用的单例模式的类有Runtime类(代表应用程序的运行环境,使应用程序能够与其运行的环境相连接);Desktop类(允许 Java 应用程序启动已在本机桌面上注册的关联应用程序)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-12-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员维他命 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 定义
  • 适用场景
  • 成员与类图
    • 成员
      • 模式类图
      • 代码示例
        • 场景概述
          • 场景分析
            • 代码实现
              • 代码对应的类图
              • 优点
              • 缺点
              • iOS SDK 和 JDK 中的应用
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档