개발/Dart

factory 키워드 (싱글턴 패턴)

leebera_ 2022. 5. 26. 21:19

class의 인스턴스를 새로 만들지 않도록 도와주는 키워드이다.(보통 싱글턴을 구현할 때 사용한다.)

싱글턴 패턴이란 class의 인스턴스를 하나만 생성하고 이를 재사용하도록 하는 디자인 패턴이다.

 

factory 키워드가 쓰인 생성자는 무조건 자기 자신 타입의 인스턴스를 반환해야 한다.

 

예시

class TestFactory {
  static final TestFactory _factoryInstance = TestFactory._internal();
​
  factory TestFactory() {
    return _factoryInstance;
  }
​
  TestFactory._internal() {
    print('call');
  }
}
​
main() {
  var testFactory1 = TestFactory();
  var testFactory2 = TestFactory();
​
  print(testFactory1 == testFactory2);
}
​
/* print Result
call
true
*/

비공개(private) 생성자인 _internal을 통해 생성된 인스턴스를 _factoryInstance에 넣어두고 생성자가 호출되면 이 인스턴스를 반환하여 싱글턴 패턴으로 사용하도록 한다.

 

여러 인스턴스를 재사용

이 경우엔 싱글턴은 아니라고 생각함

class Logger {
  final String name;
  bool mute = false;
​
  static final Map<String, Logger> _cache = <String, Logger>{};
​
  factory Logger(String name) {
    return _cache.putIfAbsent(name, () => Logger._internal(name));
  }
​
  factory Logger.fromJson(Map<String, Object> json) {
    return Logger(json['name'].toString());
  }
​
  Logger._internal(this.name) {
    print(this.name + 'call');
  }
​
  void log(String msg) {
    if (!mute) print(msg);
  }
}
​
main() {
  var logger = Logger('UI');
  var logger2 = Logger('UI2');
​
  var logMap = {'name': 'UI'};
  var loggerJson = Logger.fromJson(logMap);
​
  print(logger == logger2);
  print(logger == loggerJson);
  print(logger2 == loggerJson);
  
  /* print Result
  UIcall
  UI2call
  false
  true
  false
  */
}

dart document에 있는 코드를 살짝 바꾼 것이다.

 

putIfAbsent함수로 name의 값과 같은 key값이 map에 있는지 체크하고 있으면 _cache에 이미 있는 Logger를 반환하고 없다면 Logger의 비공개(private) 생성자인 _internal을 통해 새로 생성된 Logger를 반환한다.

 

print Result를 보면 name이 다른 logger2는 _internal이 호출되어  새로운 인스턴스가 생성되어 반환되었다.

loggerJson에 name이 UI인 json데이터를 넣어도 logger와 같은 name을 넣었으므로 logger의 인스턴스를 재사용한 것과 같아 print(logger == loggerJson); 의 결과가 true로 나오게 된 것이다.

logger2는 name이 다르므로 print(logger2 == loggerJson); 의 결과는 false가 나오게 되는 것이다.

 

 

참고

 

A tour of the Dart language

A tour of all the major Dart language features.

dart.dev