Bagaimana cara menghindari nama umum untuk kelas abstrak?

10

Secara umum ada baiknya untuk menghindari kata-kata seperti "pegangan" atau "proses" sebagai bagian dari nama rutin dan nama kelas, kecuali jika Anda berurusan dengan (misalnya) penanganan file atau (misalnya) proses unix. Namun kelas abstrak sering tidak benar-benar tahu apa yang akan mereka lakukan dengan sesuatu selain, katakanlah, proseskan. Dalam situasi saya saat ini, saya memiliki "EmailProcessor" yang masuk ke kotak masuk pengguna dan memproses pesan darinya. Tidak terlalu jelas bagi saya bagaimana memberikan nama yang lebih tepat, meskipun saya perhatikan masalah gaya berikut muncul:

  • lebih baik memperlakukan kelas turunan sebagai klien dan menamai kelas dasar dengan bagian dari fungsi yang diterapkannya? Memberinya lebih berarti tetapi akan melanggar is-a. Misalnya EmailAcquirer akan menjadi nama yang masuk akal karena mengakuisisi untuk kelas turunan, tetapi kelas turunan tidak akan memperoleh untuk siapa pun.
  • Atau hanya nama yang benar-benar kabur karena siapa yang tahu apa yang akan dilakukan kelas turunan. Namun "Prosesor" masih terlalu umum karena melakukan banyak operasi yang relevan, seperti masuk dan menggunakan IMAP.

Adakah jalan keluar dari dilema ini?

Masalah lebih jelas untuk metode abstrak, di mana Anda tidak bisa menjawab pertanyaan "apa yang dilakukan?" karena jawabannya hanyalah "apa pun yang diinginkan klien."

Djechlin
sumber
Apakah Anda memiliki sumber (dan beberapa konteks) untuk klaim "secara umum" itu? Juga, aturan penamaan tambahan untuk daftar - jangan buang waktu mencari nama yang sempurna yang mungkin tidak ada. Jika ragu, berikan nama terbaik yang Anda bisa, tambahkan deskripsi yang lebih panjang sebagai komentar di mana itu didefinisikan jika perlu, tetapi Anda dapat selalu menolak nanti jika seseorang tidak menyukai pilihan Anda atau nama sempurna tiba-tiba muncul di benak Anda ketika Anda sedang melakukan sesuatu yang lain.
Steve314
3
@ Steve314 - ya, Steve McConnell, Kode Lengkap, edisi pertama, Bab 4 atau 5 tentang rutinitas. Diskusi ekstensif tentang penamaan di bab-bab ini, pada dasarnya menyimpulkan jika Anda tidak memiliki nama baik Anda mungkin tidak memiliki fungsi yang baik.
djechlin
gagal menemukan nama baik mungkin tampak seperti pertanda buruk, tetapi IMO Anda harus tahu jika fungsinya buruk berdasarkan fungsi itu sendiri. Refactoring hanya karena bahasa Inggris tidak dirancang khusus untuk proyek Anda agak bodoh. Tidak, ini bukan masalah sehari-hari, tetapi Anda sudah memutuskan bahwa Anda memiliki masalah.
Steve314
1
@ Steve314 Pemrograman sepenuhnya tentang mengelola kompleksitas, dan jika otak Anda tidak dapat menemukan kata untuk sesuatu, ada peluang yang cukup bagus ia tidak akan dapat mengelola kompleksitasnya ketika harus melakukan hal-hal seperti menggunakannya dalam kalimat yang lebih besar atau sebagai bagian dari sistem yang lebih besar. Sebenarnya bukan klaim yang berani untuk mengatakan ketidakmampuan menemukan nama baik adalah alasan besar untuk berhenti sejenak karena khawatir. Tapi ini dibahas secara luas di McConnell, saya akan merekomendasikan membaca dua bab setidaknya setidaknya seluruh buku ini layak dibaca dari depan ke belakang.
djechlin
klaim dalam Kode Lengkap tidak seharusnya dipercaya. Saya mengetahui reputasi buku, tetapi saya juga sadar akan hal ini . Selain itu, saya telah mengelola kompleksitas dengan sangat baik selama berabad-abad - kesalahan terjadi, karena masalah, tetapi ketika ada masalah, kadang-kadang masalahnya adalah fungsi yang sangat sederhana itu jelas tidak bisa salah, tetapi tetap saja .
Steve314

Jawaban:

10

Masalahnya bukan nama, tetapi Anda menempatkan terlalu banyak dalam satu kelas.

Di kelas contoh Anda, beberapa bagian sangat konkret (bagaimana surat akan diperoleh). Bagian lain sangat abstrak (apa yang akan Anda lakukan dengan surat).

Lebih baik melakukan ini dengan kelas yang terpisah, daripada dengan warisan.

Saya menyarankan:

  • MessageIterator abstrak, disubklasifikasikan oleh POPMailBoxDownloader

  • kelas lain yang MEMILIKI POPMailBoxDownloader dan melakukan sesuatu dengan pesan.

Kris Van Bael
sumber
Ini kedengarannya benar. Kedengarannya seperti jika Anda menemukan diri Anda menamai sesuatu "processEvent" atau kelas "MessageProcessor," ada kemungkinan besar Anda bisa mendesain lebih dari komposisi daripada derivasi. Dalam hal ini adalah tradeoff, sebagai pengelola fleksibilitas dapat berguna tetapi klien akan terganggu dengan bertanya-tanya apa fungsi masing-masing (lebih banyak daripada pengelola).
djechlin
6

Jika saya tidak dapat menemukan nama yang bagus untuk suatu kelas, saya menulis dokumentasi kode sebaris untuk kelas tersebut. Ini menggambarkan tujuan kelas dalam satu aroma. Biasanya saya bisa mendapatkan nama yang bagus untuk kelas dari deskripsi ini. Ini juga bermanfaat untuk kelas abstrak.

Jika deskripsi kelas adalah "Masuk ke kotak masuk pengguna dan memproses pesan darinya", saya akan menyarankan "InboxProcessor" sebagai nama kelas. Jika kelas turunan memiliki "Masuk ke kotak masuk pengguna dan memindahkan email spam ke folder spam" sebagai deskripsi, saya akan memilih "InboxSpamMover" sebagai nama.

Saya tidak melihat masalah ketika menggunakan nama generik seperti "prosesor" jika itu mencerminkan tujuan umum dari kelas abstrak.

Jika Anda memiliki masalah dengan menjelaskan tujuan kelas dalam satu atau dua aroma, maka Anda mungkin memiliki masalah desain. Mungkin kelas melakukan terlalu banyak dan melanggar Prinsip Tanggung Jawab Tunggal . Ini juga berlaku untuk kelas abstrak.

Theo Lenndorff
sumber
2

Mengutip Frank Zappa, itu adalah apa itu dan harus dinamai demikian. Contoh Anda tidak menggali cukup dalam ke dalam apa jenis pemrosesan yang terjadi. Apakah ini sebuah EmailToTroubleTicketProcessor, sebuah EmailGrammarCorrectoratau sebuah EmailSpamDetector?

Masalah lebih jelas untuk metode abstrak, di mana Anda tidak bisa menjawab pertanyaan "apa yang dilakukan?" karena jawabannya hanyalah "apa pun yang diinginkan klien."

Itu tidak sepenuhnya benar; pertanyaan yang tidak dapat Anda jawab untuk sesuatu yang abstrak adalah " bagaimana ia melakukan apa yang dilakukannya?" karena itu spesifik implementasi. Jika suatu EmailSenderkelas memiliki DeliveryStatus deliver(Email e)metode, ada kontrak tersirat bahwa suatu implementasi akan menerima email, cobalah untuk mengirimkannya dan kembalikan beberapa status tentang bagaimana hasilnya. Anda tidak peduli apakah itu terhubung ke server SMTP atau mencetaknya untuk diikat ke merpati pos selama implementasi melakukan apa yang dijanjikan. Abstrak hanya mengukur janji itu sehingga suatu implementasi dapat mengatakan, "ya, saya melakukan itu."

Blrfl
sumber
Bagaimana dengan ketika fungsi akhirnya ada di terminal tertentu, jadi kelas abstrak mengatakan "dan ini di sini, lakukan apa pun yang Anda inginkan dengannya?" misal, metode tidak memiliki akses ke status, tipe pengembalian batal, tanpa lemparan.
djechlin
Itu masih hal yang sama. Sekalipun metode void doWhatYouDoWith(Email e)Anda, Anda masih dapat memanggil kelas an EmailDisposer, yang cukup spesifik untuk mengatakan apa yang dilakukannya tetapi cukup umum sehingga bagaimana hingga implementasi. Meskipun saya pikir @KrisVanBael berhasil: jika Anda menggunakan sesuatu yang ambigu, mungkin ada terlalu banyak di bawah satu atap.
Blrfl
0

Pikirkan mengapa buruk menggunakan kata-kata seperti itu. Apakah ini deskriptif? Kata-kata apa yang ada untuk menggambarkan kelas? EmailBaseClass? Mungkinkah itu lebih deskriptif daripada mengatakan EmailManager atau yang serupa? Kuncinya adalah memiliki wawasan tentang kelas yang dimaksud, jadi temukan kata kerja atau kata benda yang tepat. Perlakukan kode Anda seperti puisi.

zxcdw
sumber
"EmailBaseClass" akan seperti penamaan int age"ageInteger," hanya lebih buruk karena saya akan mengharapkan untuk mendapatkan email teks biasa, email MIME dll dari itu. Tidak perlu menggambarkan apa yang diawali oleh kata abstractdi tempat pertama (ini adalah Jawa). Apakah Anda memiliki wawasan khusus untuk bagian dasar dari kelas ini? Dan lebih banyak wawasan masih belum menyelesaikan masalah penamaan sesuatu yang akan melintasi hubungan is-a, saya bisa memiliki sesuatu yang terlalu kabur atau terlalu umum, saya tidak melihat jalan keluar dari ini kecuali jika saya punya lebih banyak wawasan untuk memiliki lebih banyak wawasan.
djechlin
@djechlin - ada kasus langka di mana ageIntegeratau sesuatu seperti itu sebenarnya sesuai. Notasi Hungaria adalah versi singkat dari konteks di mana itu sering terjadi. Tentu saja, ada saat-saat ketika Anda mungkin membutuhkan sesuatu di sepanjang garis ageNumericdan ageStringdalam lingkup yang sama, dengan indikasi jenis nama menjadi cara termudah dan paling jelas untuk disambiguasi.
Steve314
@djechlin Saya pribadi merasa paling mudah untuk bekerja dengan kode yang hanya bisa saya intip untuk mendapatkan pemahaman. Yaitu, nama memberi tahu saya apa yang saya kerjakan. Tidak perlu tahu apakah systemControllerkelas dasar abstrak atau daun dalam hierarki besar. Tentu saja ini dapat diatasi dengan IDE (seperti yang saya kira adalah kasus dengan sebagian besar pengembangan Java?) Yang dapat segera menginformasikan pengguna tentang isi dan struktur kelas sehingga sebenarnya nama - nama yang berwawasan tidak dapat dibenarkan dalam nada yang sama.
zxcdw