다트에서 싱글 톤을 어떻게 만드나요?
싱글 톤 패턴은 클래스의 인스턴스가 하나만 생성되도록합니다. 다트에서 어떻게 만들 수 있습니까?
Dart의 팩토리 생성자 덕분에 싱글 톤을 쉽게 구축 할 수 있습니다.
class Singleton {
static final Singleton _singleton = Singleton._internal();
factory Singleton() {
return _singleton;
}
Singleton._internal();
}
당신은 그것을 구성 할 수 있습니다 new
main() {
var s1 = Singleton();
var s2 = Singleton();
print(identical(s1, s2)); // true
print(s1 == s2); // true
}
다음은 Dart에서 싱글 톤을 만드는 여러 가지 방법을 비교 한 것입니다.
1. 팩토리 생성자
class SingletonOne {
SingletonOne._privateConstructor();
static final SingletonOne _instance = SingletonOne._privateConstructor();
factory SingletonOne(){
return _instance;
}
}
2. 게터가있는 정적 필드
class SingletonTwo {
SingletonTwo._privateConstructor();
static final SingletonTwo _instance = SingletonTwo._privateConstructor();
static SingletonTwo get instance { return _instance;}
}
3. 정적 필드
class SingletonThree {
SingletonThree._privateConstructor();
static final SingletonThree instance = SingletonThree._privateConstructor();
}
설치하는 방법
위의 싱글 톤은 다음과 같이 인스턴스화됩니다.
SingletonOne one = SingletonOne();
SingletonTwo two = SingletonTwo.instance;
SingletonThree three = SingletonThree.instance;
노트 :
나는 원래 이것을 질문 으로 물었지만 위의 모든 방법이 유효하며 선택은 개인 취향에 달려 있다는 것을 발견했다.
나는 매우 직관적 인 독서를 찾지 못했습니다 new Singleton()
. new
실제로 새 인스턴스를 작성하지 않는 것을 알기 위해 문서를 읽어야합니다 .
싱글 톤을 수행하는 또 다른 방법이 있습니다 (기본적으로 Andrew가 위에서 말한 것).
lib / thing.dart
library thing;
final Thing thing = new Thing._private();
class Thing {
Thing._private() { print('#2'); }
foo() {
print('#3');
}
}
main.dart
import 'package:thing/thing.dart';
main() {
print('#1');
thing.foo();
}
Dart의 게으른 초기화로 인해 게터가 처음 호출 될 때까지 싱글 톤이 생성되지 않습니다.
원하는 경우 싱글 톤 클래스에서 싱글 톤을 정적 게터로 구현할 수도 있습니다. 즉 Thing.singleton
, 최상위 게터 대신에.
또한 Bob Nystrom의 게임 프로그래밍 패턴 서적 에서 싱글 톤 에 대한 테이크를 읽어보십시오 .
라이브러리 내에서 전역 변수를 사용하는 것은 어떻습니까?
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에서는 싱글 톤 패턴이 필요하지만 Dart에서 먼 길을 갈 필요는없는 것 같습니다.
const 생성자 및 팩토리로 다트 싱글 톤
class Singleton {
factory Singleton() =>
const Singleton._internal_();
const Singleton._internal_();
}
void main() {
print(new Singleton() == new Singleton());
print(identical(new Singleton() , new Singleton()));
}
다른 가능한 방법은 다음과 같습니다.
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;
}
스위프트 스타일의 싱글 톤을 선호하는 사람을 위해 @Seth Ladd 답변을 수정했습니다 .shared
.
class Auth {
// singleton
static final Auth _singleton = Auth._internal();
factory Auth() => _singleton;
Auth._internal();
static Auth get shared => _singleton;
// variables
String username;
String password;
}
견본:
Auth.shared.username = 'abc';
다음은 다른 솔루션을 결합한 간결한 예입니다. 싱글 톤에 액세스하려면 다음을 수행하십시오.
singleton
인스턴스를 가리키는 전역 변수 사용- 일반적인
Singleton.instance
패턴. - 인스턴스를 반환하는 팩토리 인 기본 생성자를 사용합니다.
참고 : 싱글 톤을 사용하는 코드가 일관되도록 세 가지 옵션 중 하나만 구현해야합니다.
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 User {
final int age;
final String name;
User({
this.name,
this.age
});
static User _instance;
static User getInstance({name, age}) {
if(_instance == null) {
_instance = User(name: name, idade: age);
return _instance;
}
return _instance;
}
}
print(User.getInstance(name: "baidu", age: 24).age); //24
print(User.getInstance(name: "baidu 2").name); // is not changed //baidu
print(User.getInstance()); // {name: "baidu": age 24}
이 작동합니다.
class GlobalStore {
static GlobalStore _instance;
static GlobalStore get instance {
if(_instance == null)
_instance = new GlobalStore()._();
return _instance;
}
_(){
}
factory GlobalStore()=> instance;
}
As I'm not very fond of using the new
keyword or other constructor like calls on singletons, I would prefer to use a static getter called inst
for example:
// 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");
}
example usage:
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));
Hello what about something like this? Very simple implementation, Injector itself is singleton and also added classes into it. Of course can be extended very easily. If you are looking for something more sophisticated check this package: https://pub.dartlang.org/packages/flutter_simple_dependency_injection
void main() {
Injector injector = Injector();
injector.add(() => Person('Filip'));
injector.add(() => City('New York'));
Person person = injector.get<Person>();
City city = injector.get<City>();
print(person.name);
print(city.name);
}
class Person {
String name;
Person(this.name);
}
class City {
String name;
City(this.name);
}
typedef T CreateInstanceFn<T>();
class Injector {
static final Injector _singleton = Injector._internal();
final _factories = Map<String, dynamic>();
factory Injector() {
return _singleton;
}
Injector._internal();
String _generateKey<T>(T type) {
return '${type.toString()}_instance';
}
void add<T>(CreateInstanceFn<T> createInstance) {
final typeKey = _generateKey(T);
_factories[typeKey] = createInstance();
}
T get<T>() {
final typeKey = _generateKey(T);
T instance = _factories[typeKey];
if (instance == null) {
print('Cannot find instance for type $typeKey');
}
return instance;
}
}
참고URL : https://stackoverflow.com/questions/12649573/how-do-you-build-a-singleton-in-dart
'development' 카테고리의 다른 글
AngularJs에서 첫 번째 문자열을 대문자로 (0) | 2020.07.07 |
---|---|
SQLite 대신 MySQL을 사용하여 새로운 Ruby on Rails 애플리케이션 만들기 (0) | 2020.07.07 |
이것이 의미하는 것은 : 실패 [INSTALL_FAILED_CONTAINER_ERROR]? (0) | 2020.07.06 |
socket.io에서 클라이언트의 IP 주소를 가져옵니다 (0) | 2020.07.06 |
len (generator ())하는 방법 (0) | 2020.07.06 |