Saya mengembangkan model objek yang memiliki banyak kelas orangtua / anak yang berbeda. Setiap objek anak memiliki referensi ke objek induknya. Saya dapat memikirkan (dan telah mencoba) beberapa cara untuk menginisialisasi referensi orang tua, tetapi saya menemukan kelemahan yang signifikan untuk setiap pendekatan. Mengingat pendekatan yang dijelaskan di bawah ini mana yang terbaik ... atau apa yang lebih baik.
Saya tidak akan memastikan kode di bawah ini dikompilasi jadi silakan coba lihat maksud saya jika kode tidak benar secara sintaksis.
Perhatikan bahwa beberapa konstruktor kelas anak saya mengambil parameter (selain orang tua) meskipun saya tidak selalu menampilkannya.
Penelepon bertanggung jawab untuk mengatur orang tua dan menambahkan ke orang tua yang sama.
class Child { public Child(Parent parent) {Parent=parent;} public Parent Parent {get; private set;} } class Parent { // singleton child public Child Child {get; set;} //children private List<Child> _children = new List<Child>(); public List<Child> Children { get {return _children;} } }
Kelemahan: pengaturan induk adalah proses dua langkah untuk konsumen.
var child = new Child(parent); parent.Children.Add(child);
Kelemahan: rawan kesalahan. Penelepon dapat menambahkan anak ke orangtua yang berbeda dari yang digunakan untuk menginisialisasi anak.
var child = new Child(parent1); parent2.Children.Add(child);
Induk memverifikasi bahwa pemanggil menambahkan anak ke induk yang diinisialisasi.
class Child { public Child(Parent parent) {Parent = parent;} public Parent Parent {get; private set;} } class Parent { // singleton child private Child _child; public Child Child { get {return _child;} set { if (value.Parent != this) throw new Exception(); _child=value; } } //children private List<Child> _children = new List<Child>(); public ReadOnlyCollection<Child> Children { get {return _children;} } public void AddChild(Child child) { if (child.Parent != this) throw new Exception(); _children.Add(child); } }
Kelemahan: Pemanggil masih memiliki proses dua langkah untuk pengaturan induk.
Kelemahan: pengecekan runtime - mengurangi kinerja dan menambahkan kode ke setiap add / setter.
Orang tua menetapkan referensi orang tua anak (untuk dirinya sendiri) ketika anak ditambahkan / ditugaskan ke orang tua. Setter induk adalah internal.
class Child { public Parent Parent {get; internal set;} } class Parent { // singleton child private Child _child; public Child Child { get {return _child;} set { value.Parent = this; _child = value; } } //children private List<Child> _children = new List<Child>(); public ReadOnlyCollection<Child> Children { get {return _children;} } public void AddChild(Child child) { child.Parent = this; _children.Add(child); } }
Kelemahan: Anak dibuat tanpa referensi orang tua. Terkadang inisialisasi / validasi memerlukan induk yang berarti beberapa inisialisasi / validasi harus dilakukan di setter induk anak. Kode dapat menjadi rumit. Akan jauh lebih mudah untuk menerapkan anak jika selalu memiliki referensi orang tuanya.
Orang tua memperlihatkan metode penambahan pabrik sehingga seorang anak selalu memiliki referensi orang tua. Aktor anak adalah internal. Setter induk bersifat pribadi.
class Child { internal Child(Parent parent, init-params) {Parent = parent;} public Parent Parent {get; private set;} } class Parent { // singleton child public Child Child {get; private set;} public void CreateChild(init-params) { var child = new Child(this, init-params); Child = value; } //children private List<Child> _children = new List<Child>(); public ReadOnlyCollection<Child> Children { get {return _children;} } public Child AddChild(init-params) { var child = new Child(this, init-params); _children.Add(child); return child; } }
Kelemahan: Tidak dapat menggunakan sintaks inisialisasi seperti
new Child(){prop = value}
. Sebaliknya harus dilakukan:var c = parent.AddChild(); c.prop = value;
Kelemahan: Harus menduplikasi parameter konstruktor anak dalam metode pabrik tambahan.
Kelemahan: Tidak dapat menggunakan properti setter untuk anak tunggal. Tampaknya lumpuh bahwa saya memerlukan metode untuk mengatur nilai tetapi memberikan akses baca melalui pengambil properti. Itu miring.
Child menambahkan dirinya ke orang tua yang dirujuk dalam konstruktornya. Ctor anak adalah publik. Tidak ada publik menambahkan akses dari orang tua.
//singleton class Child{ public Child(ParentWithChild parent) { Parent = parent; Parent.Child = this; } public ParentWithChild Parent {get; private set;} } class ParentWithChild { public Child Child {get; internal set;} } //children class Child { public Child(ParentWithChildren parent) { Parent = parent; Parent._children.Add(this); } public ParentWithChildren Parent {get; private set;} } class ParentWithChildren { internal List<Child> _children = new List<Child>(); public ReadOnlyCollection<Child> Children { get {return _children;} } }
Kelemahan: sintaks panggilan tidak bagus. Biasanya seseorang memanggil
add
metode pada orang tua alih-alih hanya membuat objek seperti ini:var parent = new ParentWithChildren(); new Child(parent); //adds child to parent new Child(parent); new Child(parent);
Dan menetapkan properti daripada hanya membuat objek seperti ini:
var parent = new ParentWithChild(); new Child(parent); // sets parent.Child
...
Saya baru tahu bahwa SE tidak mengizinkan beberapa pertanyaan subjektif dan jelas ini adalah pertanyaan subjektif. Tapi, mungkin itu adalah pertanyaan subjektif yang bagus.