从Flutter范儿的单例来看Dart的构造函数

5004a577ec8defdda16fa67c2760de3d.png

点击上方蓝字关注我,知识会给你力量

340fd3e17bfff2683a7a8f4c8e9a36ff.png

单例模式

单例模式应该是设计模式中使用的最广泛的一种设计模式了,在Kotlin中,甚至为它单独创建了一个语法糖——object类,来快速实现单例模式,而在Dart中,并没有像Kotlin这样的语法糖,所以,参考单例的一般实现,我们可以很容易的实现下面这样一个单例。

class Singleton {
  static Singleton? _instance;

  // 私有的命名构造函数
  Singleton._private() {
    // TODO
  }

  static Singleton getInstance() {
    if (_instance == null) {
      _instance = Singleton._private();
    }
    return _instance!;
  }
}

上面的代码与大部分编程语言的代码都差不多,不外乎就是单例的几个特点:

  • 私有构造函数

  • 静态instance访问

在Dart中,变量和函数前面加上「_」就代表私有,但这个私有实际上的含义是「只能在当前文件中访问」,所以,如果在当前文件中,你依然是可以访问这个私有变量或者函数的。另外,由于Dart是单线程模型,所以也不存在线程安全的问题,不用做线程控制。

上面的代码,作为一个Dart初学者来说,是无可厚非的,但是对于老司机来说,明显没有Flutter范儿,所以,我们借助Dart的语法糖,来改造下上面的单例代码。

class Singleton {
  static Singleton? _instance;

  // 私有的命名构造函数
  Singleton._private() {
    // TODO
  }

  static Singleton get instance => _instance ??= Singleton._private();
}

首先,通过「??=」来简化空判断,其次,通过get函数来获取实例,将instance函数变成了instance变量。这样一来,代码简化了不少,而且也更加简单了。

不过,这依然不是最具Flutter范儿的单例写法,在Dart中,它提供了一个factory关键字,与Kotlin中的object关键字,有异曲同工之妙,我们来看看官方推荐的单例写法。

class Singleton {
  static final Singleton _singleton = Singleton._internal();

  factory Singleton() => _singleton;

  Singleton._internal() {
    // TODO
  }
}

�所谓的factory constructor,它的作用是「仅在第一次创建实例,后续都返回相同的实例」,这不就是天然的单例吗,所以,借助factory constructor,我们可以很方便的写出一个Flutter范儿的单例。

构造函数

构造函数是一个类在初始化时,主动调用的函数,在Dart中,有多种不同的构造函数,它们在不同的场景下使用,可以极大的简化我们的代码,同时也让我们的代码更加具有Flutter范儿。

默认构造函数

缺省构造函数不用自己创建,如果一个类没有构造函数,那么它会自动添加一个,它什么都不做。

// Default Constructor
class Test {
  String name = 'xys';
  Test();
}

在构造函数中初始化变量

Dart提供了多种不同的方式在构造函数中未变量赋值,其中最简单的,就是在构造时初始变量。

// Constructor with parameters
class Test {
  String name;
  Test(this.name);
}

其实Test(this.name)实际上就是Test(String name){this.name = name}的简化写法。

同时,构造函数也可以增加方法体,进行一些初始化逻辑。

// Constructor with the initial method
class Test {
  String name;
  Test(this.name) {
    // TODO
  }
}

�当你需要在构造函数初始化时给变量赋值时,可以通过initializer list来实现。

// Constructor with initializer
class Test {
  String name;
  
  Test(name) : name = handleSth(name);
  
  static String handleSth(String e) => e.toUpperCase();
}

initializer list可以初始化多个变量,它们之间可以使用「,」进行分隔,如果有super构造器,那么它一般放在最后。

如果你要override基类的变量,那么可以通过super关键字来覆写。

// Constructor with super()
class Base {
  String id;
  Base(this.id);
}
class Test extends Base {
  String name;
  Test(this.name, String id) : super(id);
}

另外,构造函数中,还支持通过Asserts�来做一些检查。

// Constructor with assertion
class Test {
  String name;
  Test(this.name) : assert(name.length > 3);
}

对于Dart的参数来说,通常我们设置的都是必选参数,就是类似我们上面的这些参数,而在Dart中,还可以设置可选参数。

class Test {
  String name;

  Test(this.name, [int sex = 0]);
}

Test('xys', 1);

或者你觉得可选参数在使用时的语义不太明确,那么你可以使用具名参数。

class Test {
  String name;

  Test(this.name, {int sex = 0});
}

Test('xys', sex: 1);

这样在使用时,语义会更加明确。

私有构造函数

私有构造函数,除了我们前面提到的单例使用场景外,下面这个场景,也使用的很多。

class Utils {
  Utils._();
  static void log(String message) => print(message);
}

通过私有构造函数,我们可以避免使用者创建工具类的实例,而是让使用者直接调用静态函数。

具名构造函数

具名构造函数可以给当前的构造逻辑起一个别名,方便调用者通过语义来进行调用。

// Constructor with this()
class Test {
  String name;
  int sex;
  Test(this.name, this.sex);
  Test.boy(String name) : this(name, 1);
  Test.girl(String name) : this(name, 0);
}

const构造函数

const构造函数在Flutter中使用的非常多,因为一个const构造函数是不可变的,const构造函数在运行时会指向内存空间的同一个对象,从而提高代码执行的效率,所以,在Flutter中,如果一个Widget是可以定义为const的,那就把它定义为const吧。

factory构造函数

factory constructor前面我们已经讲解过了,它可以从另一个构造函数,或者是其它类,返回一个唯一的实例。最常用的场景就是单例的使用,我们来看下它的另一个使用场景,即从缓存中返回唯一实例。

class Test {
  final String name;

  static final _cache = <String, Test>{};

  Test._(this.name);

  factory Test(name) => _cache[name] ??= Test._(name);
}

factory构造函数与static method的区别

在大部分时间,这两者都是非常类似的,甚至是可以混用的,但是它们之间,还是有一些区别的。

对于factory constructor来说,它不需要命名,也不用指定通用参数,这样可以减少很多模板代码,我们来看下面这个例子。

class ComplexClass<Value, Notifier extends ValueNotifier<Value>> {}

在这个例子中,它包含一个比较复杂的泛型,如果我们要创建一个静态工厂,那么就需要这样:

class ComplexClass<Value, Notifier extends ValueNotifier<Value>> {
  static ComplexClass<Value, Notifier> someFactory<ComplexClass<Value, Notifier extends ValueNotifier<Value>>() {
    // TODO: return a ComplexClass instance
  }
}

我们需要创建很复杂的参数类型,但是使用factory constructor,则可以避免这些模板代码。

class ComplexClass<Value, Notifier extends ValueNotifier<Value>> {
  factory ComplexClass.someFactory() {
    // TODO: return a ComplexClass instance
  }
}

向大家推荐下我的网站 https://www.yuque.com/xuyisheng  点击原文一键直达

专注 Android-Kotlin-Flutter 欢迎大家访问

往期推荐

  • 从源码看Flutter Android端的启动流程

  • Flutter鸿蒙终端一体化—鹊桥相会

  • Flutter鸿蒙终端一体化-珠联璧合

  • Flutter鸿蒙终端一体化-混沌初开

本文原创公众号:群英传,授权转载请联系微信(Tomcat_xu),授权后,请在原创发表24小时后转载。

< END >

作者:徐宜生

更文不易,点个“三连”支持一下👇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/606261.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

某盾BLACKBOX逆向关键点

需要准备的东西&#xff1a; 1、原JS码 2、AST解混淆码 3、token(来源于JSON) 一、原JS码很好获取&#xff0c;每次页面刷新&#xff0c;混淆的代码都会变&#xff0c;这是正常&#xff0c;以下为部分代码 while (Qooo0) {switch (Qooo0) {case 110 14 - 55: {function O0…

Win10/11共享文件夹,访问提示需要输入用户名密码

Win10/11共享文件夹&#xff0c;访问提示需要输入用户名密码 问题 已经关闭了密码保护共享&#xff0c;但是局域网其他电脑访问该文件夹&#xff0c;提示需要输入用户名和密码 解决方法 操作步骤 1.按WINR键打开运行&#xff0c;输入gpedit.msc打开本地组策略编辑器 2.按如…

五种算法(BWO、RUN、SO、HO、GWO)求解复杂城市地形下无人机路径规划,可以修改障碍物及起始点(MATLAB)

一、算法介绍 &#xff08;1&#xff09;白鲸优化算法BWO 参考文献&#xff1a;Zhong C, Li G, Meng Z. Beluga whale optimization: A novel nature-inspired metaheuristic algorithm[J]. Knowledge-Based Systems, 2022, 109215. &#xff08;2&#xff09;龙格-库塔优化…

【Android学习】简单的登录页面和业务逻辑实现

实现功能 1 登录页&#xff1a;密码登录和验证码登录 2 忘记密码页&#xff1a;修改密码 3 页面基础逻辑 java代码 基础页面 XML login_main.xml <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.and…

Agent AI:智能代理的未来

&#x1f388;写在前面 &#x1f64b;‍♂️大家好呀&#xff0c;我是超梦梦梦梦 &#x1f64b;‍♂️ 小伙伴们如果在学习过程中有不明白的地方&#xff0c;欢迎评论区留言提问&#xff0c;小梦定知无不言&#xff0c;言无不尽。 目录 一、Agent AI的起源与发展 二、Agent A…

js,JavaScript 对象(2024-05-02)

对象是 JavaScript 的数据类型之一。 对象用于存储键/值&#xff08;名称/值&#xff09;集合。 JavaScript 对象是命名值的集合。 下例创建具有四个键/值属性的 JavaScript 对象&#xff1a; const person {firstName: "Bill",lastName: "Gates",age:…

Linux中的简单操作 ls/tar/pwd/cd/mkdir/touch 等

目录 前言 安装和卸载软件包 ls 查看指定路径下的文件和文件夹 tar 解压缩/压缩命令 pwd 查看当前路径 cd 改变目录 mkdir 创建目录 递归创建 rm rmdir 删除文件或目录 touch 创建文件 ll、echo、重定向符&#xff08;>,>>&#xff09; ll echo 重定向符…

嵌入式C语言高级教程:实现基于STM32的无线远程监控系统

无线远程监控系统可以广泛应用于安防、环境监测等领域&#xff0c;提供实时数据传输和警报功能。本教程将指导您如何在STM32微控制器上实现一个基本的无线远程监控系统。 一、开发环境准备 硬件要求 微控制器&#xff1a;STM32L476RG&#xff0c;特别适合低功耗应用。开发板…

MySQL数据库实验三

本文承接前面的俩次实验基础上完成&#xff0c;不过实现的都是基础操作的练习 目录 目录 前言 实验目的 实验要求 实验内容及步骤 updata操作 delete操作 alter操作 添加列 删除列 修改列的数据类型 要求实现 实验结果 代码结果 注意事项 思考题 总结 前言 本文是MySQL数据库…

c++11 lambda 捕获,匿名,返回类型后置

lambda就是即写即用的匿名函数&#xff0c;可以用于解决匹配函数参数的问题 int main(int argc,char *argv[]) {vector<int> v{1,2,3,4,5,6,7,8};for_each(v.begin(),v.end(),[](int a){cout<<a;});return 0; } for_each是固定函数&#xff0c;我们需要他但是又没…

MySQL中JOIN连接的实现算法

目录 嵌套循环算法&#xff08;NLJ&#xff09; 简单嵌套循环&#xff08;SNLJ&#xff09; 索引嵌套循环&#xff08;INLJ&#xff09; 块嵌套循环&#xff08;BNLJ&#xff09; 三种算法比较 哈希连接算法&#xff08;Hash Join&#xff09; 注意事项&#xff1a; 工…

分享5个免费AI一键生成毕业论文的网站

一、引言 对于忙碌的学生来说&#xff0c;毕业论文通常是一项艰巨的任务。幸运的是&#xff0c;随着人工智能技术的发展&#xff0c;现在有一些工具可以帮助学生轻松完成论文。本文将介绍五个免费的AI工具&#xff0c;它们能够一键帮助你生成毕业论文&#xff0c;让你的学术生…

Linux流程控制

if语句 基本格式 if condition thencommand1 fi 写成一行 if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi if-else语句 格式 if condition thencommand1 command2...commandN elsecommand fi if else- if else if condition1 th…

wordpress忘记后台密码,在数据库中修改回来,然后再修改回去。

源地址&#xff1a;https://www.ctvol.com/seoomethods/1421332.html 我们在做wordpess运维的时候&#xff0c;都会遇到很尴尬的时候&#xff0c;有时候在错误运维中&#xff0c;不知道删除了什么东西&#xff0c;造成wordpress后台不能登录&#xff0c;后台页面也直接失效&am…

Google Chrome浏览器便携增强版 v124.0.6367.61

01 软件介绍 Google Chrome v124.0.6367.61&#xff0c;这一版本经过精心设计&#xff0c;集成了一系列的功能增强和关键补丁&#xff0c;旨在提升用户体验。其中&#xff0c;Chrome引入了便携性数据保存选项&#xff0c;优化了标签页及标签栏的操作机制。此外&#xff0c;它还…

互联网黑话知所多少?

互联网黑话是互联网公司形成的一套带有浓厚互联网行业特色的“非正式语言”。这些黑话通常起源于社交媒体、网络论坛、技术博客以及职场交流中&#xff0c;它们可能是缩写词、行业术语、梗或者其它专业领域的词汇。来盘一盘你常听、常用的互联网黑话都有哪些吧&#xff01;

分布式与一致性协议之ZAB协议(七)

ZAB协议 ZAB协议:如何处理读写请求 你应该有这样的体会&#xff0c;如果你想了解一个网络服务&#xff0c;执行的第一个功能肯定是写操作&#xff0c;然后才会执行读操作。比如&#xff0c;你要了解ZooKeeper&#xff0c;那么肯定会在zkClient.sh命令行中执行写操作(比如crea…

SAP PP学习笔记09 - 作业区(工作中心Work Center)Customize2(管理码,班次顺序,计算式),标准Text,作业区阶层

上文讲了作业区&#xff08;工作中心&#xff09;的概念及其中重要字段&#xff0c;以及作业区的部分Customize。 SAP PP学习笔记08 - 作业区&#xff08;工作中心Work Center&#xff09;&#xff0c;作业区Customize-CSDN博客 本文继续讲 作业区的Customize。 Spro > 生…

杨氏矩阵查找算法

有一个数字矩阵&#xff0c;矩阵的每行从左到右是递增的&#xff0c;矩阵从上到下是递增的&#xff0c;请编写程序在这样的矩阵中查找某个数字是否存在。 要求&#xff1a;时间复杂度小于O(N); 1.首先更直观地了解一下杨氏矩阵&#xff1a; 123456789 这就是一个简单的杨氏矩…

【Java】初识网络编程

文章目录 前言✍一、互联网的发展1.独立模式2.网络的出现局域网LAN广域网WAN ✍二、网络编程概述✍三、网络编程中的术语介绍IP地址端口号协议OSI七层模型TCP\IP四层模型 ✍四、协议的层级之间是如何配合工作的 前言 在本文中&#xff0c;会对网络编程的一些术语进行解释&#…
最新文章