Jawaban terlambat tetapi saya tidak bisa menolak.
Apakah X sebagian besar kelas menjadi Y baik atau anti-pola?
Dalam kebanyakan kasus, sebagian besar aturan, diterapkan tanpa berpikir, sebagian besar akan salah besar (termasuk yang ini).
Izinkan saya menceritakan sebuah kisah tentang kelahiran suatu benda di tengah kekacauan beberapa kode prosedur yang benar, cepat dan kotor, yang terjadi, bukan karena desain, tetapi karena putus asa.
Magang saya dan saya adalah pasangan pemrograman untuk dengan cepat membuat beberapa kode membuang untuk mengikis halaman web. Kami sama sekali tidak punya alasan untuk mengharapkan kode ini akan berumur panjang, jadi kami hanya mengeluarkan sesuatu yang berhasil. Kami mengambil seluruh halaman sebagai string dan memotong barang-barang yang kami butuhkan dengan cara yang paling rapuh yang bisa Anda bayangkan. Jangan menilai. Berhasil.
Sekarang sambil melakukan ini saya membuat beberapa metode statis untuk melakukan pemotongan. Magang saya menciptakan kelas DTO yang sangat mirip dengan Anda CatData
.
Ketika saya pertama kali melihat DTO itu menyadap saya. Tahun-tahun kerusakan yang telah dilakukan Jawa pada otak saya membuat saya mundur di bidang-bidang publik. Tapi kami bekerja di C #. C # tidak perlu pengambil dan setter prematur untuk mempertahankan hak Anda untuk membuat data tidak berubah, atau dienkapsulasi nanti. Tanpa mengubah antarmuka, Anda dapat menambahkannya kapan saja. Mungkin agar Anda dapat mengatur breakpoint. Semua tanpa memberi tahu klien Anda tentang hal itu. Ya C #. Boo Java.
Jadi saya memegang lidah saya. Saya menyaksikan ketika dia menggunakan metode statis saya untuk menginisialisasi hal ini sebelum menggunakannya. Kami memiliki sekitar 14 di antaranya. Itu jelek, tapi kami tidak punya alasan untuk peduli.
Kemudian kami membutuhkannya di tempat lain. Kami mendapati diri kami ingin menyalin dan menempelkan kode. 14 baris inisialisasi dilemparkan. Itu mulai terasa menyakitkan. Dia ragu-ragu dan meminta saya untuk ide.
Dengan enggan saya bertanya, "apakah Anda akan mempertimbangkan objek?"
Dia melihat kembali DTO-nya dan mengacaukan wajahnya. "Ini adalah objek".
"Maksudku, benda yang nyata"
"Hah?"
"Biarkan aku menunjukkan sesuatu padamu. Kamu memutuskan apakah itu berguna"
Saya memilih nama baru dan cepat-cepat mengambil sesuatu yang tampak seperti ini:
public class Cat{
CatData(string catPage) {
this.catPage = catPage
}
private readonly string catPage;
public string name() { return chop("name prefix", "name suffix"); }
public string weight() { return chop("weight prefix", "weight suffix"); }
public string image() { return chop("image prefix", "image suffix"); }
private string chop(string prefix, string suffix) {
int start = catPage.indexOf(prefix) + prefix.Length;
int end = catPage.indexOf(suffix);
int length = end - start;
return catPage.Substring(start, length);
}
}
Ini tidak melakukan apa pun yang belum dilakukan metode statis. Tapi sekarang saya mengisap 14 metode statis ke dalam kelas di mana mereka bisa sendirian dengan data yang mereka kerjakan.
Saya tidak memaksa magang saya untuk menggunakannya. Saya hanya menawarkannya dan membiarkannya memutuskan apakah dia ingin tetap menggunakan metode statis. Saya pulang ke rumah berpikir dia mungkin akan tetap pada apa yang sudah dia kerjakan. Hari berikutnya saya menemukan dia menggunakannya di banyak tempat. Itu mendeklarasikan sisa kode yang masih jelek dan prosedural tetapi kompleksitas ini sekarang tersembunyi dari kita di belakang suatu objek. Itu sedikit lebih baik.
Sekarang yakin setiap kali Anda mengaksesnya ini melakukan sedikit pekerjaan yang adil. DTO adalah nilai cache cepat yang bagus. Saya khawatir tentang itu tetapi menyadari bahwa saya bisa menambahkan caching jika kita perlu tanpa menyentuh salah satu kode yang digunakan. Jadi saya tidak akan repot sampai kita peduli.
Apakah saya mengatakan Anda harus selalu menempel pada objek OO di atas DTO? Tidak. DTO bersinar ketika Anda harus melewati batas yang membuat Anda tidak bisa bergerak. DTO punya tempat mereka.
Tapi begitu juga objek OO. Pelajari cara menggunakan kedua alat. Pelajari berapa biaya masing-masing. Belajarlah untuk membiarkan masalah, situasi, dan magang memutuskan. Dogma bukan temanmu di sini.
Karena jawaban saya sudah lama sekali, izinkan saya membebaskan Anda dari beberapa kesalahpahaman dengan meninjau kode Anda.
Sebagai contoh, suatu kelas biasanya memiliki anggota dan metode kelas, misalnya:
public class Cat{
private String name;
private int weight;
private Image image;
public void printInfo(){
System.out.println("Name:"+this.name+",weight:"+this.weight);
}
public void draw(){
//some draw code which uses this.image
}
}
Di mana konstruktor Anda? Ini tidak cukup menunjukkan kepada saya untuk mengetahui apakah itu berguna.
Tetapi setelah membaca tentang prinsip tanggung jawab tunggal dan prinsip tertutup terbuka, saya lebih suka memisahkan kelas menjadi kelas DTO dan pembantu dengan metode statis saja, misalnya:
public class CatData{
public String name;
public int weight;
public Image image;
}
public class CatMethods{
public static void printInfo(Cat cat){
System.out.println("Name:"+cat.name+",weight:"+cat.weight);
}
public static void draw(Cat cat){
//some draw code which uses cat.image
}
}
Saya pikir ini sesuai dengan prinsip tanggung jawab tunggal karena sekarang tanggung jawab CatData adalah hanya menyimpan data, tidak peduli dengan metode (juga untuk CatMethods).
Anda dapat melakukan banyak hal konyol atas nama Prinsip Tanggung Jawab Tunggal. Saya bisa berpendapat bahwa Cat Strings dan Cat int harus dipisahkan. Metode menggambar dan Gambar itu semua harus memiliki kelas sendiri. Bahwa program Anda yang sedang berjalan adalah tanggung jawab tunggal sehingga Anda hanya boleh memiliki satu kelas. : P
Bagi saya, cara terbaik untuk mengikuti Prinsip Tanggung Jawab Tunggal adalah dengan menemukan abstraksi yang baik yang memungkinkan Anda memasukkan kerumitan dalam sebuah kotak sehingga Anda dapat menyembunyikannya. Jika Anda bisa memberikannya nama baik yang membuat orang tidak terkejut dengan apa yang mereka temukan ketika mereka melihat ke dalam, Anda telah mengikutinya dengan cukup baik. Mengharapkannya untuk mendikte lebih banyak keputusan maka itu meminta masalah. Jujur, kedua daftar kode Anda melakukan itu jadi saya tidak melihat mengapa SRP penting di sini.
Dan itu juga sesuai dengan prinsip tertutup terbuka karena menambahkan metode baru tidak perlu mengubah kelas CatData.
Baik tidak Prinsip buka tutup bukan tentang menambahkan metode baru. Ini tentang bisa mengubah implementasi metode lama dan tidak perlu mengedit apa pun. Tidak ada yang menggunakan Anda dan bukan metode lama Anda. Sebaliknya Anda menulis beberapa kode baru di tempat lain. Suatu bentuk polimorfisme akan melakukannya dengan baik. Jangan lihat itu di sini.
Pertanyaan saya adalah, apakah ini baik atau anti-pola?
Nah, bagaimana saya bisa tahu? Lihat, melakukannya bagaimanapun memiliki manfaat dan biaya. Ketika Anda memisahkan kode dari data, Anda dapat mengubah salah satu tanpa harus mengkompilasi ulang yang lain. Mungkin itu sangat penting bagi Anda. Mungkin itu hanya membuat kode Anda rumit tanpa tujuan.
Jika itu membuat Anda merasa lebih baik, Anda tidak jauh dari sesuatu yang Martin Fowler sebut sebagai objek parameter . Anda tidak harus hanya mengambil primitif ke objek Anda.
Apa yang saya ingin Anda lakukan adalah mengembangkan rasa untuk melakukan pemisahan Anda, atau tidak, dalam gaya pengkodean. Karena percaya atau tidak Anda tidak dipaksa untuk memilih gaya. Anda hanya harus hidup dengan pilihan Anda.