Misalkan saya memiliki berbagai entitas dalam model saya (menggunakan EF), katakanlah Pengguna, Produk, Faktur dan Pesanan.
Saya menulis kontrol pengguna yang dapat mencetak ringkasan objek entitas dalam aplikasi saya di mana entitas milik set yang ditentukan sebelumnya, dalam hal ini saya mengatakan bahwa ringkasan Pengguna dan Produk dapat diringkas.
Ringkasan semua hanya memiliki ID dan deskripsi, jadi saya membuat antarmuka sederhana untuk ini:
public interface ISummarizableEntity {
public string ID { get; }
public string Description { get; }
}
Kemudian untuk entitas yang dimaksud, saya membuat kelas parsial yang mengimplementasikan antarmuka ini:
public partial class User : ISummarizableEntity
{
public string ID
{
get{ return UserID.ToString(); }
}
public string Description
{
get{ return String.Format("{0} {1} is from {2} and is {3} years old", FirstName, LastName, Country, Age); }
}
}
public partial class Product: ISummarizableEntity
{
public string ID
{
get{ return ProductID.ToString(); }
}
public string Description
{
get{ return String.Format("{0} weighs {1}{2} and belongs in the {3} department", ProductName, WeightValue, WeightUnit, Department); }
}
}
Dengan cara ini kontrol pengguna saya / tampilan parsial hanya dapat mengikat koleksi ISummarizableEntity dan tidak perlu tertarik pada sumber sama sekali. Saya telah diberitahu bahwa antarmuka tidak boleh digunakan sebagai tipe data tetapi saya tidak mendapatkan informasi lebih dari itu. Sejauh yang saya bisa lihat, meskipun antarmuka biasanya menggambarkan perilaku, hanya menggunakan properti bukan merupakan anti-pola itu sendiri karena properti hanyalah gula sintaksis untuk getter / setter.
Saya bisa membuat tipe data dan peta konkret dari entitas untuk itu tetapi saya tidak bisa melihat manfaatnya. Saya bisa membuat objek entitas mewarisi dari kelas abstrak dan kemudian mendefinisikan properti tetapi kemudian saya mengunci entitas untuk tidak digunakan lebih lanjut karena kita tidak dapat memiliki banyak pewarisan. Saya juga terbuka untuk memiliki objek yang ISummarizableEntity jika saya mau (jelas saya akan mengganti nama antarmuka)
Solusi yang saya gunakan dalam pikiran saya dapat dipertahankan, dapat dikembangkan, diuji dan cukup kuat. Bisakah Anda melihat anti-pola di sini?
EntitySummary
, denganUser
danProduct
masing-masing memiliki metode sepertipublic EntitySummary GetSummary()
?Jawaban:
Antarmuka tidak menggambarkan perilaku. Justru sebaliknya, kadang-kadang.
Antarmuka menggambarkan kontrak, seperti "jika saya menawarkan objek ini ke metode apa pun yang menerima ISummarizableEntity, objek ini harus berupa entitas yang dapat meringkas sendiri" - dalam kasus Anda, yang didefinisikan sebagai mampu mengembalikan suatu ID string dan Deskripsi string.
Itu penggunaan antarmuka yang sempurna. Tidak ada anti-pola di sini.
sumber
List
yang tidak berperilaku seperti daftar?Anda telah memilih jalur yang lebih baik untuk desain ini karena Anda mendefinisikan tipe perilaku tertentu yang akan diperlukan dari beberapa jenis objek yang berbeda. Warisan dalam hal ini akan menyiratkan hubungan yang sama antara kelas-kelas yang sebenarnya tidak ada. Dalam hal ini, kompabilitas lebih disukai daripada warisan.
sumber
Antarmuka yang hanya membawa properti harus dihindari karena:
Di sini Anda mencampur dua masalah:
Ringkasan dibuat dari dua string: id dan deskripsi. Ini data biasa:
Sekarang setelah Anda menentukan ringkasan apa yang ingin Anda tetapkan kontrak:
Perhatikan bahwa menggunakan intelijen dalam getter adalah anti-pola dan harus dihindari: itu harus ditempatkan dalam fungsi. Berikut ini tampilan implementasi:
sumber