Dart memberi nama konstruktor, metode statis, dan konstruktor pabrik

Diberikan kode berikut:

const jsonString = '{"myString":"Hello"}';
final jsonMap = jsonDecode(jsonString);

final myObject = MyClass.fromJson(jsonMap);

Berapa banyak cara untuk membuat objek baru menggunakan sintaks ini:

MyClass.fromJson(jsonMap)

Baru-baru ini saya mencoba memahami perbedaan antara konstruktor bernama, konstruktor pabrik, dan metode statis, jadi saya memposting jawaban saya di bawah sehingga saya memiliki sesuatu untuk dijadikan referensi di masa mendatang.


person Suragch    schedule 07.08.2020    source sumber


Jawaban (2)


Untuk membuat instance baru dari suatu objek menggunakan sintaks berikut:

MyClass.fromJson(jsonMap)

Untuk digunakan dengan kode berikut:

// import 'dart:convert';

const jsonString = '{"myString":"Hello"}';
final jsonMap = jsonDecode(jsonString);

final myObject = MyClass.fromJson(jsonMap);

Setidaknya ada cara berikut untuk melakukannya (dengan catatan tambahan tentang karakteristik masing-masing):

Konstruktor generatif

class MyClass {
  MyClass(this.myString);
  final String myString;

  MyClass.fromJson(Map<String, dynamic> json) : this(json['myString']);
}

Ada dua jenis konstruktor generatif: bernama dan tidak disebutkan namanya. MyClass.fromJson() adalah konstruktor bernama sedangkan MyClass() adalah konstruktor tanpa nama. Prinsip-prinsip berikut berlaku untuk konstruktor generatif:

  • Konstruktor generatif hanya dapat membuat instance kelas itu sendiri.
  • Konstruktor generatif dapat menggunakan daftar penginisialisasi.
  • Konstruktor generatif hanya boleh menggunakan parameter inisialisasi atau daftar penginisialisasi untuk menyetel properti final, yaitu, bukan di badan konstruktor.
  • Konstruktor generatif dapat berupa const, meskipun tidak dialihkan.

Konstruktor pabrik

class MyClass {
  MyClass(this.myString);
  final String myString;

  factory MyClass.fromJson(Map<String, dynamic> json) {
    return MyClass(json['myString']);
  }
}
  • Konstruktor pabrik dapat mengembalikan subtipe kelas.
  • Konstruktor pabrik dapat digunakan untuk membuat lajang.
  • Konstruktor pabrik tidak dapat disebutkan namanya seperti konstruktor generatif.
  • Konstruktor pabrik bisa const, tetapi hanya saat mengarahkan ulang.

Metode statis

class MyClass {
  MyClass(this.myString);
  final String myString;

  static MyClass fromJson(Map<String, dynamic> json) {
    return MyClass(json['myString']);
  }
}
  • Metode statis dapat menghasilkan apa pun, termasuk Masa Depan.
  • Metode statis dapat digunakan untuk membuat lajang.
  • Metode statis dapat digunakan sebagai sobek.

Bacaan lebih lanjut

person Suragch    schedule 07.08.2020
comment
Apa yang Anda maksud dengan Named constructors may only use the initializer list to set final properties.? bahkan dengan konstruktor bernama seperti MyClass.named(this.myString) Anda dapat menginisialisasi properti akhir. Anda juga dapat membuat lajang menggunakan konstruktor factory seperti di sini - person Mattia; 07.08.2020
comment
@Mattia, terima kasih telah menunjukkan hal itu. Maksud saya adalah bahwa properti akhir tidak dapat disetel di badan konstruktor bernama, tapi saya tidak cukup spesifik. Saya memperbarui jawaban saya untuk yang itu. Mengenai lajang, saya sudah menyebutkannya. (Namun, menempatkannya dalam metode statis juga mungkin membuatnya tampak seperti satu-satunya cara untuk membuat singleton. Apakah itu benar?) - person Suragch; 07.08.2020
comment
@lrn Saya mendapat kesan bahwa konstruktor generatif adalah konstruktor tanpa nama, yaitu konstruktor yang hanya menggunakan nama kelas. Apakah itu tidak benar? - person Suragch; 08.08.2020
comment
@lrn Saya mengajukan pertanyaan saya lebih detail di sini: stackoverflow.com/questions/63313102/ - person Suragch; 08.08.2020
comment
Dijawab di sana, tapi tidak, itu tidak benar. Menjadi generatif atau pabrik adalah ortogonal untuk diberi nama atau tidak. Konstruktor pabrik adalah yang diawali dengan factory, sisanya generatif. Bisa diberi nama atau tidak disebutkan namanya. - person lrn; 09.08.2020

Selain jawaban terinci @suragch. Saya ingin memberikan beberapa poin yang menunjukkan factory constructor adalah opsi terbaik untuk skenario di atas (untuk metode fromJson()).

  • Saat menggunakan konstruktor pabrik, Anda tidak perlu menginisialisasi variabel instan kelas tersebut. (tetapi ketika Anda menggunakan konstruktor generatif, perlu menginisialisasi semua variabel instan akhir)

  • Konstruktor pabrik dapat mengembalikan objek yang sudah ada. Misalnya:- saat menggunakan paket json_seriazible, metode fromJson() mengembalikan objek yang sudah ada (yang dibuat sebelumnya). Jadi kita hanya bisa menggunakan konstruktor pabrik dengan paket ini.

  • Konstruktor pabrik dapat mengembalikan subtipe apa pun dari kelas tersebut, namun saat menggunakan konstruktor generatif, konstruktor hanya dapat mengembalikan objek tipe persis dari kelas tersebut.

  • Memastikan hanya satu instance kelas yang pernah dibuat (pola tunggal). (objeknya mahal, jadi pola tunggal diperlukan untuk fromJson)

Berdasarkan poin di atas, kita dapat melihat konstruktor generatif menambahkan lebih banyak batasan untuk konstruktor fromJson dan metode statis memberikan lebih sedikit batasan untuk fromJson sehingga dapat menyebabkan kesalahan tipe dengan mengembalikan objek tipe berbeda.

person TDM    schedule 21.04.2021
comment
Untuk poin 4 Anda, saya akan memenuhi syarat dengan mengatakan itu dapat digunakan untuk membuat singleton. Namun, konstruktor pabrik juga dapat digunakan untuk membuat objek baru setiap saat. - person Suragch; 21.04.2021
comment
@Suragch [Jika konstruktor pabrik mengembalikan objek yang ada =› pola tunggal Benar (poin 4 benar.)] [Tetapi jika konstruktor pabrik mengembalikan panggilan konstruktor (buat instance baru) =› pola tunggal Salah (poin 4 salah.) I pikir ini adalah poin yang ingin Anda katakan. Apakah saya benar? - person TDM; 21.04.2021
comment
Ya itu benar. - person Suragch; 22.04.2021