Apa pro dan kontra dari memiliki metode pembuatan objek statis di atas konstruktor?
class Foo {
private Foo(object arg) { }
public static Foo Create(object arg) {
if (!ValidateParam(arg)) { return null; }
return new Foo(arg);
}
}
Beberapa yang bisa saya pikirkan:
Pro:
- Kembalikan nol alih-alih melempar pengecualian (beri nama
TryCreate
). Ini dapat membuat kode lebih singkat dan bersih di sisi klien. Klien jarang mengharapkan konstruktor gagal. - Buat berbagai jenis objek dengan semantik yang jelas, misalnya
CreatFromName(String name)
danCreateFromCsvLine(String csvLine)
- Dapat mengembalikan objek yang di-cache jika perlu, atau implementasi yang diturunkan.
Cons:
- Kurang dapat ditemukan, lebih sulit untuk membaca skim.
- Beberapa pola, seperti serialisasi atau refleksi lebih sulit (misalnya
Activator<Foo>.CreateInstance()
)
design-patterns
dbkk
sumber
sumber
Foo x = Foo.TryCreate(); if (x == null) { ... }
). Menangani pengecualian ctor adalah (Foo x; try { x = new Foo(); } catch (SomeException e) { ... }
). Saat memanggil metode normal, saya lebih suka pengecualian untuk kode kesalahan, tetapi dengan pembuatan objek,TryCreate
tampaknya lebih bersih.Name
danCsvLine
mengetik, daripada mengungkapkan persyaratan melalui nama metode. Ini akan memungkinkan Anda untuk membuat berlebihan. Menggunakan string untuk keduanya dapat dianggap sebagai "obsesi primitif" (dengan asumsi Anda tidak membuat pilihan ini karena alasan kinerja yang diketahui). Lihatlah Object Calisthenics untuk mengetahui cara yang menyenangkan untuk menjelajahi ini.Jawaban:
Kelemahan terbesar dengan ' pembuat ' statis mungkin membatasi pewarisan. Jika Anda atau pengguna perpustakaan Anda mendapatkan kelas dari Anda
Foo
, makaFoo::Create()
menjadi sangat tidak berguna. Semua logika yang didefinisikan di sana harus ditulis ulang lagi di dalam warisanCreate()
.Saya akan menyarankan kompromi: mendefinisikan konstruktor dengan logika inisialisasi objek trivial yang tidak pernah gagal / melempar, kemudian mendefinisikan pencipta (s) dengan caching, konstruksi alternatif dll. Itu meninggalkan kemungkinan derivasi dan Anda mendapat manfaat dari memiliki pencipta untuk kelas tertentu .
sumber
Buat adalah metode Pabrik. Ketika saya merasa perlu untuk ini, saya menerapkan pola Pabrik, dan mendefinisikan antarmuka untuk mewakili kontrak untuk membuat objek serta kelas pelaksana, yang kemudian akan disuntikkan di mana diperlukan. Ini mempertahankan keuntungan dari memindahkan tanggung jawab penciptaan keluar dari kelas, tetapi menghindari (atau setidaknya membuat lebih jelas) keterbatasan melakukan penciptaan objek di luar konstruktor kelas.
sumber