Flutter中的设计模式(一)--如何设计一个单例

Flutter中的设计模式 -- 如何设计一个单例

前言

使用flutter日常开发过程中,经常会用到单例这种设计模式。最开始的时候是模仿java中的写法,但后来随着对Dart语言特性的了解,发现其实Dart中单例的写法与java代码应该是有很大差别的,这是由于两种语言不同的特性所致。所以,这次想从单例开始,把flutter中所有常用到的设计模式全部都整理归纳一下,可能会更新的比较慢(^ - ^)。

单例模式

单例设计模式(Singleton Design Pattern)理解起来非常简单。一个类只允许创建一个对象(或者实例),那这个类就是一个单例类,这种设计模式就叫作单例设计模式,简称单例模式。
那单例这种设计模式被设计出来是为了解决什么问题呢?
某些类考虑到每次新建实例内存开销较大或者存在多个实例资源访问冲突的问题,这个时候我们就需要将其设计为单例,即全局公用一个实例,这样一方面可以减少内存的消耗,一方面也可以避免资源访问冲突的问题(本篇文章着重介绍flutter中单例使用方法,不过多介绍单例设计思想,可自行查阅资料)。

Java中的单例

一个典型的懒汉式(支持延迟加载)与支持高并发(双重检测加锁)的java单例写法如下所示:

public class Singleton {
    
     
  private static Singleton instance;
  private Singleton() {
    
    }
  public static Singleton getInstance() {
    
    
    if (instance == null) {
    
    
      synchronized(Singleton.class) {
    
    
        if (instance == null) {
    
    
          instance = new Singleton();
        }
      }
    }
    return instance;
  }
}

代码原理不在这里解释,可查阅相关资料。
由模版代码可以归纳出单例的一般模式:
类构造函数通常为私有,确保不能从类外部实例化该类;
单例类(Singleton)中包含一个引用自身类的静态属性实例(instance);
该实例只能通过静态方法 getInstance() 访问,在这个方法内创建实例,并且判断是否已创建,防止重复创建;
部分像java这种多线程语言需要考虑线程安全与并发时性能问题。

Dart中的单例-基础版

然后我们可以根据上面总结出的模式写一个简单的Dart版本单例来:

class Singleton {
    
    
  static Singleton _instance;
  // 私有的命名构造函数,声明后会覆盖默认的无参构造函数
  Singleton._internal();
  static Singleton getInstance() {
    
    
    if (_instance == null) {
    
    
      _instance = Singleton._internal();
    }
    return _instance;
  }
}
final singleton = Singleton.getInstance()

可以看到,基本是遵循了一般的模式去写的,针对dart语法做了一些修改。另外,由于Dart 是单线程模型的语言,所有的代码通常都运行在同一个 isolate 中,因此不需要考虑线程安全的问题,把双重检测与加锁的代码去掉了。

Dart中的单例-升级版

之前的代码还有很多java的痕迹,我们接下来逐步使用dart语言的特性继续改造这个单例。

  1. 我们可以使用getter 操作符,简化我们的代码:
class Singleton {
    
    
  static Singleton _instance;
  static get instance {
    
    
    if (_instance == null) {
    
    
      _instance = Singleton._internal();
    }
    return _instance;
  }
  // 私有的命名构造函数,声明后会覆盖默认的无参构造函数
  Singleton._internal();
}
.....
final singleton = Singleton.instance
  1. 我们还可以使用工厂构造函数(factory constructor):工厂构造函数不需要每次构建新的实例,且不会自动生成实例,而是通过代码来决定返回的实例对象;工厂构造函数类似于 static 静态成员,无法访问 this 指针;一般需要依赖其他类型构造函数;工厂构造函数还可以实现单例;
class Singleton {
    
    
  static Singleton _instance;
  // 私有的命名构造函数,声明后会覆盖默认的无参构造函数
  Singleton._internal();
  // 工厂构造函数 
  factory Singleton() {
    
    
    if (_instance == null) {
    
    
      _instance = Singleton._internal();
    }
    return _instance;
  }
}
....
final singleton = Singleton()

至此,我们的Dart版单例就大功告成了。

猜你喜欢

转载自blog.csdn.net/Yaoobs/article/details/131561539
今日推荐