单例模式确保只创建一个类的实例。我如何在达特建立这个?


当前回答

因为我不太喜欢使用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));

其他回答

下面是一个组合了其他解决方案的简洁示例。可以通过以下方式访问单例对象:

使用指向实例的单例全局变量。 通用单例。模式实例。 使用默认构造函数,它是一个返回实例的工厂。

注意:您应该只实现三个选项中的一个,以便使用单例的代码保持一致。

Singleton get singleton => Singleton.instance;
ComplexSingleton get complexSingleton => ComplexSingleton._instance;

class Singleton {
  static final Singleton instance = Singleton._private();
  Singleton._private();
  factory Singleton() => instance;
}

class ComplexSingleton {
  static ComplexSingleton _instance;
  static ComplexSingleton get instance => _instance;
  static void init(arg) => _instance ??= ComplexSingleton._init(arg);

  final property;
  ComplexSingleton._init(this.property);
  factory ComplexSingleton() => _instance;
}

如果需要进行复杂的初始化,则必须在稍后在程序中使用实例之前进行。

例子

void main() {
  print(identical(singleton, Singleton.instance));        // true
  print(identical(singleton, Singleton()));               // true
  print(complexSingleton == null);                        // true
  ComplexSingleton.init(0); 
  print(complexSingleton == null);                        // false
  print(identical(complexSingleton, ComplexSingleton())); // true
}

在阅读了所有的选项后,我想到了这个,这让我想起了一个“经典的单例”:

class AccountService {
  static final _instance = AccountService._internal();

  AccountService._internal();

  static AccountService getInstance() {
    return _instance;
  }
}

这是另一种可能的方式:

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;
}

在这个例子中,当我想要使用Singleton时,我做了其他必要的事情。例如:

将一个值传递给单例对象的构造函数 在构造函数内部初始化一个值 为Singleton的变量设置一个值 能够访问和访问这些值。

是这样的:

class MySingleton {

  static final MySingleton _singleton = MySingleton._internal();

  String _valueToBeSet;
  String _valueAlreadyInSingleton;
  String _passedValueInContructor;

  get getValueToBeSet => _valueToBeSet;

  get getValueAlreadyInSingleton => _valueAlreadyInSingleton;

  get getPassedValueInConstructor => _passedValueInContructor;

  void setValue(newValue) {
    _valueToBeSet = newValue;
  }

  factory MySingleton(String passedString) {
    _singleton._valueAlreadyInSingleton = "foo";
    _singleton._passedValueInContructor = passedString;

    return _singleton;
  }

  MySingleton._internal();
}

MySingleton的用法:

void main() {

MySingleton mySingleton =  MySingleton("passedString");
mySingleton.setValue("setValue");
print(mySingleton.getPassedValueInConstructor);
print(mySingleton.getValueToBeSet);
print(mySingleton.getValueAlreadyInSingleton);

}

由const构造函数和工厂组成的Dart单例

class Singleton {
  factory Singleton() =>
    Singleton._internal_();
  Singleton._internal_();
}
 
 
void main() {
  print(new Singleton() == new Singleton());
  print(identical(new Singleton() , new Singleton()));
}