单例模式确保只创建一个类的实例。我如何在达特建立这个?
当前回答
这里有一个简单的答案:
类应具有其类型的私有和静态属性。 构造函数应该是私有的,以防止外部对象初始化。 检查实例是否为空,如果是,创建一个实例并返回,否则返回现有实例。
实现(延迟加载)
class Singleton {
static Singleton? _instance;
Singleton._();
static Singleton get instance => _instance ??= Singleton._();
void someMethod(){
...
}
...
}
实现(急装)
class Singleton {
static Singleton _instance = Singleton._();
Singleton._();
static Singleton get instance => _instance;
void someMethod(){
...
}
...
}
使用
Singleton.instance.someMethod();
其他回答
在库中使用全局变量怎么样?
single.dart:
library singleton;
var Singleton = new Impl();
class Impl {
int i;
}
main.dart:
import 'single.dart';
void main() {
var a = Singleton;
var b = Singleton;
a.i = 2;
print(b.i);
}
或者这是不受欢迎的?
单例模式在Java中是必要的,因为在Java中不存在全局变量的概念,但在Dart中似乎不需要绕这么长的路。
因为我不太喜欢使用new关键字或其他构造函数,比如对单例对象的调用,我更喜欢使用一个名为inst的静态getter:
// the singleton class
class Dao {
// singleton boilerplate
Dao._internal() {}
static final Dao _singleton = new Dao._internal();
static get inst => _singleton;
// business logic
void greet() => print("Hello from singleton");
}
使用示例:
Dao.inst.greet(); // call a method
// Dao x = new Dao(); // compiler error: Method not found: 'Dao'
// verify that there only exists one and only one instance
assert(identical(Dao.inst, Dao.inst));
这里有一个简单的答案:
类应具有其类型的私有和静态属性。 构造函数应该是私有的,以防止外部对象初始化。 检查实例是否为空,如果是,创建一个实例并返回,否则返回现有实例。
实现(延迟加载)
class Singleton {
static Singleton? _instance;
Singleton._();
static Singleton get instance => _instance ??= Singleton._();
void someMethod(){
...
}
...
}
实现(急装)
class Singleton {
static Singleton _instance = Singleton._();
Singleton._();
static Singleton get instance => _instance;
void someMethod(){
...
}
...
}
使用
Singleton.instance.someMethod();
这就是我如何在我的项目中实现单例
灵感来自flutter firebase => FirebaseFirestore.instance.collection('collectionName')
class FooAPI {
foo() {
// some async func to api
}
}
class SingletonService {
FooAPI _fooAPI;
static final SingletonService _instance = SingletonService._internal();
static SingletonService instance = SingletonService();
factory SingletonService() {
return _instance;
}
SingletonService._internal() {
// TODO: add init logic if needed
// FOR EXAMPLE API parameters
}
void foo() async {
await _fooAPI.foo();
}
}
void main(){
SingletonService.instance.foo();
}
来自我的项目的例子
class FirebaseLessonRepository implements LessonRepository {
FirebaseLessonRepository._internal();
static final _instance = FirebaseLessonRepository._internal();
static final instance = FirebaseLessonRepository();
factory FirebaseLessonRepository() => _instance;
var lessonsCollection = fb.firestore().collection('lessons');
// ... other code for crud etc ...
}
// then in my widgets
FirebaseLessonRepository.instance.someMethod(someParams);
这是另一种可能的方式:
void main() {
var s1 = Singleton.instance;
s1.somedata = 123;
var s2 = Singleton.instance;
print(s2.somedata); // 123
print(identical(s1, s2)); // true
print(s1 == s2); // true
//var s3 = new Singleton(); //produces a warning re missing default constructor and breaks on execution
}
class Singleton {
static final Singleton _singleton = new Singleton._internal();
Singleton._internal();
static Singleton get instance => _singleton;
var somedata;
}