factory

factory는 새로운 인스턴스를 생성하고 싶지 않을 때 사용하는 생성자이다. 이와 같은 개념은 새로운 게 아니다. 소프트웨어 디자인 패턴 중 '싱글톤 패턴'을 따른 것이다.

Singleton 패턴

전역 변수를 사용하지 않고 객체를 하나만 생성 하도록 하며, 생성된 객체를 어디에서든지 참조할 수 있도록 하는 패턴

싱글톤 패턴의 사용하는 이유

메모리 측면

최초 한번의 new 연산자를 통해서 고정된 메모리 영역을 사용하기 때문에 추후 해당 객체에 접근할 때 메모리 낭비를 방지

이미 생성된 인스턴스를 활용하니 속도 측면에서도 이점

데이터 공유가 쉽다

싱글톤 인스턴스가 전역으로 사용되는 인스턴스이기 때문에 다른 클래스의 인스턴스들이 접근하여 사용할 수 있다

도메인 관점에서 인스턴스가 한 개만 존재하는 것을 보증하고 싶은 경우 싱글톤 패턴을 사용

factory의 특징

  • 기존에 이미 생성된 인스턴스가 있다면 return 하여 재사용한다.
  • 하나의 클래스에서 하나의 인스턴스만 생성한다(싱글톤 패턴).
  • 서브 클래스 인스턴스를 리턴할 때 사용할 수 있다.
  • Factory constructors 에서는 this 에 접근할 수 없다.

factory는 '클래스와 같은 타입의 인스턴스' 또는 '메서드를 구현하는 인스턴스'를 리턴하기만 하면 된다. 이렇게 생성된 인스턴스는기존에 생성된 인스턴스가 아니라면 새롭게 생성되고, 기존 인스턴스가 있다면 기존 것을 리턴한다.

factory 보단 warehouse 창고의 의미와 유사하다.

실사용 예

class NewsArticle {
  final String title, description, urlToImage, url;

  NewsArticle({this.title, this.description, this.urlToImage, this.url});

  factory NewsArticle.fromJSON(Map<String, dynamic> json) {
    return NewsArticle(
      title: json["title"],
      description: json["description"],
      urlToImage: json["urlToImage"],
      url: json["url"],
    );
  }
}
class AccountModel {
  AccountModel({
    this.avatar,
    this.id,
    this.iso6391,
    this.iso31661,
    this.name,
    this.includeAdult,
    this.username,
  });

  Avatar? avatar;
  int? id;
  String? iso6391;
  String? iso31661;
  String? name;
  bool? includeAdult;
  String? username;

  factory AccountModel.fromJson(Map<String, dynamic> json) => AccountModel(
        avatar: Avatar.fromJson(json["avatar"]),
        id: json["id"],
        iso6391: json["iso_639_1"],
        iso31661: json["iso_3166_1"],
        name: json["name"],
        includeAdult: json["include_adult"],
        username: json["username"],
      );

  Map<String, dynamic> toJson() => {
        "avatar": avatar!.toJson(),
        "id": id,
        "iso_639_1": iso6391,
        "iso_3166_1": iso31661,
        "name": name,
        "include_adult": includeAdult,
        "username": username,
      };
}
class Logger {
  final String name;
  bool mute = false;

  // _cache is library-private, thanks to
  // the _ in front of its name.
  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);

  void log(String msg) {
    if (!mute) print(msg);
  }
}
728x90

'Study > Dart' 카테고리의 다른 글

[Dart] future, async, await, 실행순서  (0) 2021.06.15
[Dart] const 와 final 이해하기  (0) 2021.06.15
[Dart] Future, Isolate  (0) 2021.06.08
[Dart] 상속을 쓰는 이유  (0) 2021.06.07
[Dart] 상속  (0) 2021.06.07

+ Recent posts