String hardcoding yang tidak akan pernah berubah

39

Jadi, dalam upaya saya untuk menulis sebuah program untuk mengkonjugasikan kata kerja (secara algoritmik, bukan melalui dataset) untuk bahasa Prancis, saya menemukan sedikit masalah.

Algoritma untuk mengkonjugasikan kata kerja sebenarnya cukup sederhana untuk 17 atau lebih kasus kata kerja, dan berjalan pada pola tertentu untuk setiap kasus; dengan demikian, sufiks konjugasi untuk 17 kelas ini bersifat statis dan akan (sangat mungkin) tidak berubah dalam waktu dekat. Sebagai contoh:

// Verbs #1 : (model: "chanter")
    terminations = {
        ind_imp: ["ais", "ais", "ait", "ions", "iez", "aient"],
        ind_pre: ["e", "es", "e", "ons", "ez", "ent"],
        ind_fut: ["erai", "eras", "era", "erons", "erez", "eront"],
        participle: ["é", "ant"]
    };

Ini adalah sufiks infleksi untuk kelas kata kerja yang paling umum dalam bahasa Prancis.

Ada kelas-kelas lain dari kata kerja (irreguler), yang konjugasinya juga sangat mungkin tetap statis untuk satu atau dua abad berikutnya. Karena tidak teratur, konjugasi lengkapnya harus dimasukkan secara statis, karena konjugasi tidak dapat diandalkan dari suatu pola (hanya ada juga [menurut hitungan saya] 32 irreguler). Sebagai contoh:

// "être":
    forms = {
        ind_imp: ["étais", "étais", "était", "étions", "étiez", "étaient"],
        ind_pre: ["suis", "es", "est", "sommes", "êtes", "sont"],
        ind_fut: ["serai", "seras", "sera", "serons", "serez", "seront"],
        participle: ["été", "étant"]
    };

Saya bisa memasukkan semua ini ke XML atau bahkan JSON dan membatalkan deserialize ketika itu perlu digunakan, tetapi apakah ada benarnya? String ini adalah bagian dari bahasa alami, yang memang berubah, tetapi pada tingkat yang lambat.

Kekhawatiran saya adalah bahwa dengan melakukan hal-hal dengan cara yang "benar" dan deserialisasi beberapa sumber data, saya tidak hanya rumit masalah yang tidak perlu rumit, tetapi saya juga benar-benar kembali melacak seluruh tujuan dari pendekatan algoritmik: untuk tidak menggunakan sumber data! Dalam C #, saya hanya bisa membuat kelas di bawah namespace Verb.Conjugation(misalnya class Irregular) untuk menempatkan string ini dalam tipe enumerated atau sesuatu, daripada memasukkannya ke dalam XML dan membuat a class IrregularVerbDeserializer.

Jadi pertanyaannya: apakah itu sesuai untuk string hard-code yang sangat tidak mungkin berubah selama masa aplikasi? Tentu saja saya tidak dapat menjamin 100% bahwa mereka tidak akan berubah, tetapi risiko vs biaya hampir sepele untuk ditimbang di mata saya - hardcoding adalah ide yang lebih baik di sini.

Sunting : Duplikat yang diajukan menanyakan bagaimana cara menyimpan sejumlah besar string statis , sementara pertanyaan saya adalah kapan saya harus membuat hard- string string statis ini .

Chris Cirefice
sumber
26
Mungkinkah Anda ingin menggunakan perangkat lunak ini untuk bahasa lain selain Prancis di masa mendatang?
10
Pendekatan algoritmik atau tidak, jelas bahwa Anda hanya perlu melakukan hardcode pada string 32 * 20 ini (dan lebih banyak lagi ketika Anda menambahkan lebih banyak bahasa), dan satu-satunya pertanyaan sebenarnya adalah di mana harus meletakkannya. Saya akan memilih mana pun yang paling nyaman bagi Anda, yang sepertinya akan menjadi kode untuk saat ini. Anda selalu dapat mengocoknya nanti.
Ixrec
1
@ ChrisCirefice Kedengarannya cukup optimal bagi saya. Lakukan untuk itu.
Ixrec
2
@ Goddor Saya tidak berpikir Anda membaca dengan jelas - saya katakan pola konjugasi kemungkinan tidak akan pernah berubah, atau perubahan sangat jarang sehingga setiap 100 tahun kompilasi ulang akan lebih baik. Tentu saja kodenya akan berubah, tetapi begitu string ada di sana seperti yang saya inginkan, kecuali jika saya refactoring mereka akan statis untuk 100 tahun ke depan.
Chris Cirefice
1
+1. Belum lagi bahwa dalam 60-100 tahun biayanya tidak akan ada, atau telah diganti dengan versi yang lebih baik sama sekali.
HarryCBurn

Jawaban:

56

apakah ini sesuai untuk string hard-code yang sangat tidak mungkin berubah selama masa aplikasi? Tentu saja saya tidak dapat menjamin 100% bahwa mereka tidak akan berubah, tetapi risiko vs biaya hampir sepele untuk ditimbang di mata saya - hardcoding adalah ide yang lebih baik di sini

Sepertinya saya menjawab pertanyaan Anda sendiri.

Salah satu tantangan terbesar yang kita hadapi adalah memisahkan hal-hal yang cenderung berubah dari hal-hal yang tidak akan berubah. Beberapa orang menjadi gila dan membuang semua yang mereka bisa ke dalam file konfigurasi. Yang lain pergi ke ekstrim lain dan membutuhkan kompilasi ulang untuk perubahan yang paling jelas sekalipun.

Saya akan menggunakan pendekatan yang paling mudah untuk diterapkan sampai saya menemukan alasan kuat untuk membuatnya lebih rumit.

Dan Pichelman
sumber
Terima kasih Dan, itu yang saya kira. Menulis skema XML untuk ini, memiliki file lain untuk melacak, dan harus menulis antarmuka untuk deserialisasi data hanya tampak seperti mengingat terlalu banyak mengingat ada tidak banyak string, dan karena itu bahasa alami, tidak mungkin berubah secara drastis dalam 100 tahun ke depan. Untungnya, saat ini dalam bahasa pemrograman kami memiliki cara yang bagus untuk mengabstraksi data mentah ini di belakang antarmuka yang tampak bagus, misalnya French.Verb.Irregular.Etreyang akan berisi data dari pertanyaan saya. Saya pikir itu bekerja dengan baik;)
Chris Cirefice
3
+1 Di sini dari kamp Ruby, saya akan memulai hal-hal hardcoding dan memindahkannya ke konfigurasi yang diperlukan. Jangan terlalu dini merekayasa proyek Anda dengan membuat berbagai hal dapat dikonfigurasi. Itu hanya memperlambat Anda.
Overbryd
2
Catatan: beberapa grup memiliki definisi berbeda "hardcoding," jadi ketahuilah bahwa istilah itu berarti banyak hal. Ada anti-pola yang dikenali dengan baik di mana Anda mengkodekan nilai ke dalam pernyataan fungsi, alih-alih membuat struktur data seperti yang Anda miliki ( if (num == 0xFFD8)). Contoh itu harus menjadi sesuatu seperti if (num == JPEG_MAGIC_NUMBER)di hampir semua kasus untuk alasan keterbacaan. Saya hanya menunjukkannya karena kata "hardcoding" sering menimbulkan bulu di leher orang (seperti milik saya) karena makna kata alternatif ini.
Cort Ammon
@CortAmmon JPEG memiliki banyak angka ajaib. Tentunya JPEG_START_OF_IMAGE_MARKER?
user253751
@immibis Pilihan Anda untuk penamaan konstan mungkin lebih baik daripada saya.
Cort Ammon
25

Anda beralasan pada ruang lingkup yang salah.

Anda belum mengkodekan satu-satunya kata kerja individual. Anda telah mendodekan bahasa dan aturannya . Ini, pada gilirannya, berarti bahwa aplikasi Anda tidak dapat digunakan untuk bahasa lain, dan tidak dapat diperpanjang dengan aturan lain.

Jika ini maksud Anda (yaitu menggunakannya hanya untuk bahasa Prancis), ini adalah pendekatan yang tepat, karena YAGNI. Tetapi Anda mengakui bahwa Anda juga ingin menggunakannya nanti untuk bahasa lain, yang artinya segera, Anda harus memindahkan semua bagian yang sudah dikodekan ke file konfigurasi. Pertanyaan yang tersisa adalah:

  • Apakah Anda, dengan kepastian mendekati 100%, dalam waktu dekat, memperluas aplikasi ke bahasa lain? Jika demikian, Anda seharusnya mengekspor barang ke file JSON atau XML (untuk kata-kata, bagian dari kata, dll.) Dan bahasa dinamis (untuk aturan) sekarang daripada memaksa diri Anda untuk menulis ulang bagian utama aplikasi Anda.

  • Atau hanya ada kemungkinan kecil bahwa aplikasi akan diperpanjang di suatu tempat di masa depan, dalam hal mana YAGNI menentukan bahwa pendekatan paling sederhana (yang Anda gunakan saat ini) lebih baik?

Sebagai ilustrasi, ambil pemeriksa ejaan Microsoft Word. Menurut Anda, berapa banyak hal yang dikodekan dengan hardcode?

Jika Anda mengembangkan prosesor teks, Anda bisa mulai dengan mesin ejaan sederhana dengan aturan hardcode dan bahkan kata - kata if word == "musik": suggestSpelling("music");. Dengan cepat, Anda akan mulai memindahkan kata, lalu mengatur sendiri di luar kode Anda. Jika tidak:

  • Setiap kali Anda harus menambahkan kata, Anda harus mengkompilasi ulang.
  • Jika Anda mempelajari aturan baru, Anda harus mengubah kode sumber sekali lagi.
  • Dan yang lebih penting, tidak mungkin Anda dapat menyesuaikan mesin ke Jerman atau Jepang tanpa menulis kode dalam jumlah besar.

Saat Anda menyorot diri sendiri:

Sangat sedikit aturan dari bahasa Perancis yang dapat diterapkan pada bahasa Jepang.

Segera setelah Anda meng-hardcode aturan untuk suatu bahasa, setiap yang lain akan membutuhkan kode yang semakin banyak, terutama mengingat kompleksitas bahasa alami.

Subjek lain adalah bagaimana Anda mengekspresikan aturan yang berbeda, jika tidak melalui kode. Pada akhirnya, Anda mungkin menemukan bahwa bahasa pemrograman adalah alat terbaik untuk itu. Dalam hal ini, jika Anda perlu memperpanjang mesin tanpa mengkompilasi ulang, bahasa dinamis mungkin merupakan alternatif yang baik.

Arseni Mourzenko
sumber
1
Yah tentu saja tidak semuanya ada kode-keras di sana: P jadi saya kira itu benar-benar turun untuk menentukan seperti apa tampilan antarmuka yang saya inginkan sehingga saya bisa menerapkannya ke beberapa bahasa. Masalahnya adalah saya belum tahu semua bahasa dengan cukup baik, jadi itu tidak mungkin. Saya pikir satu hal yang mungkin Anda lewatkan adalah bahwa pola konjugasi (ini yang saya bicarakan) sangat statis dalam suatu bahasa, dan itu benar-benar sesuatu yang bersifat kasus per kasus. Ada sekitar 17 pola konjugasi dalam bahasa Prancis untuk kata kerja. Ini tidak akan diperpanjang dalam waktu dekat ...
Chris Cirefice
4
Saya tidak setuju - Saya pikir tidak masuk akal untuk memindahkan apa pun di luar kode sebelum muncul secara alami melalui refactoring. Mulailah dengan satu bahasa, tambahkan yang lain - pada beberapa titik implementasi ILanguageRule akan membagikan kode yang cukup sehingga hanya lebih efisien untuk memiliki satu implementasi yang diparameterisasi dengan XML (atau file lain). Tetapi meskipun begitu Anda mungkin berakhir dengan bahasa Jepang yang memiliki struktur yang sama sekali berbeda. Mulai dengan mendorong antarmuka Anda menjadi XML (atau serupa) hanya memohon untuk memiliki perubahan pada antarmuka daripada implementasinya.
ptyx
2
Catatan: jika Anda ingin menambahkan lebih banyak bahasa, itu tidak berarti memindahkan bahasa ke file konfigurasi! Anda juga bisa memiliki LanguageProcessorkelas dengan beberapa subclass. (Secara efektif, "file konfigurasi" sebenarnya adalah sebuah kelas)
user253751
2
@MainMa: Mengapa Anda menganggapnya masalah untuk dikompilasi ulang saat menambahkan kata? Anda harus mengkompilasi ulang saat melakukan perubahan lain pada kode, dan daftar kata mungkin merupakan bagian dari kode yang paling tidak mungkin berubah seiring waktu.
JacquesB
3
Saya menduga bahwa fleksibilitas untuk dapat kode aturan tata bahasa yang sangat spesifik dari masing-masing bahasa dalam subkelas akan lebih nyaman pada akhirnya daripada kemampuan untuk memuat aturan yang sama entah bagaimana dari file konfigurasi (karena pada dasarnya Anda akan menulis Anda bahasa pemrograman sendiri untuk menafsirkan konfigurasi).
David K
15

String harus diekstraksi ke file konfigurasi atau database ketika nilai-nilai bisa berubah secara independen dari logika program.

Sebagai contoh:

  • Mengekstrak teks UI ke file sumber daya. Ini memungkinkan non-programmer untuk mengedit dan membaca bukti teks, dan memungkinkan menambahkan bahasa baru dengan menambahkan file sumber daya lokal baru.

  • Mengekstrak string koneksi, url ke layanan eksternal, dll. Ke file konfigurasi. Ini memungkinkan Anda untuk menggunakan konfigurasi yang berbeda di lingkungan yang berbeda, dan untuk mengubah konfigurasi dengan cepat karena mungkin perlu diubah karena alasan di luar aplikasi Anda.

  • Pemeriksa ejaan yang memiliki kamus kata untuk diperiksa. Anda dapat menambahkan kata dan bahasa baru tanpa mengubah logika program.

Tetapi ada juga overhead kompleksitas dengan mengekstraksi ke konfigurasi, dan itu tidak selalu masuk akal.

String dapat di- hardcode ketika string aktual tidak dapat berubah tanpa mengubah logika program.

Contoh:

  • Kompiler untuk bahasa pemrograman. Kata kunci tidak diekstraksi ke konfigurasi, karena setiap kata kunci memiliki semantik spesifik yang harus didukung oleh kode dalam kompiler. Menambahkan kata kunci baru akan selalu membutuhkan perubahan kode, jadi tidak ada nilai dalam mengekstraksi string ke file konfigurasi.
  • Menerapkan protokol: Misalnya. klien HTTP akan memiliki string hardcoded seperti "DAPATKAN", "tipe konten" dll. Di sini string adalah bagian dari spesifikasi protokol, sehingga mereka adalah bagian dari kode yang paling tidak mungkin berubah.

Dalam kasus Anda, saya pikir jelas bahwa kata-kata adalah bagian yang terintegrasi dari logika program (karena Anda sedang membangun konjugator dengan aturan khusus untuk kata-kata tertentu), dan mengekstraksi kata-kata ini ke file eksternal tidak memiliki nilai.

Jika Anda menambahkan bahasa baru, Anda tetap harus menambahkan kode baru, karena setiap bahasa memiliki logika konjugasi tertentu.


Beberapa menyarankan agar Anda dapat menambahkan semacam mesin aturan yang memungkinkan Anda menentukan aturan konjugasi untuk bahasa yang arbitrer, sehingga bahasa baru dapat ditambahkan murni dengan konfigurasi. Pikirkan baik-baik sebelum Anda menyusuri jalan itu, karena bahasa manusia sangat aneh sehingga Anda perlu mesin aturan yang sangat ekspresif. Anda pada dasarnya akan menciptakan bahasa pemrograman baru (DSL konjugasi) untuk keuntungan yang meragukan. Tetapi Anda sudah memiliki bahasa pemrograman yang Anda inginkan yang dapat melakukan apa pun yang Anda butuhkan. Bagaimanapun, YAGNI.

JacquesB
sumber
1
Sebenarnya, dalam komentar kepada MainMa, saya menyebutkan bahwa menulis DSL untuk ini tidak ada gunanya karena sangat sedikit bahasa alami yang cukup mirip untuk membuatnya sepadan dengan usaha. Mungkin bahasa Prancis / Spanyol / Italia akan cukup dekat , tetapi tidak sepadan dengan usaha ekstra mengingat bahwa jumlah aturan sangat statis dalam bahasa apa pun. Poin lain yang Anda sebutkan tentang kompleksitas adalah kekhawatiran saya yang sebenarnya, dan saya pikir Anda sangat memahami apa yang saya tanyakan dalam pertanyaan saya dan memberikan jawaban yang bagus dengan contoh, jadi +1!
Chris Cirefice
5

Saya setuju 100% dengan jawaban Dan Pichelman, tetapi saya ingin satu hal ditambahkan. Pertanyaan yang harus Anda tanyakan pada diri Anda di sini adalah "siapa yang akan mempertahankan / memperluas / memperbaiki daftar kata?". Jika selalu orang yang juga memelihara aturan bahasa tertentu (pengembang tertentu, saya kira Anda), maka tidak ada gunanya menggunakan file konfigurasi eksternal jika ini membuat segalanya lebih rumit - Anda tidak akan mendapat manfaat dari ini. Dari sudut pandang ini, masuk akal untuk membuat hardcode daftar kata tersebut bahkan jika Anda harus mengubahnya dari waktu ke waktu, selama itu cukup untuk mengirimkan daftar baru sebagai bagian dari versi baru.

(Di sisi lain, jika ada sedikit peluang seseorang harus dapat mempertahankan daftar di masa depan, atau jika Anda perlu mengubah daftar kata tanpa menggunakan versi baru aplikasi Anda, maka gunakan file terpisah.)

Doc Brown
sumber
Ini adalah poin yang bagus - namun, saya sangat mungkin bahwa saya akan menjadi satu-satunya orang yang benar-benar menjaga kode, setidaknya untuk beberapa tahun ke depan. Bagian yang baik tentang hal ini adalah bahwa meskipun string akan dikodekan secara keras, itu adalah serangkaian string / aturan yang sangat kecil yang tidak mungkin berubah dalam waktu dekat (karena itu adalah bahasa alami, yang tidak berevolusi terlalu banyak tahun ke tahun). -tahun). Yang mengatakan, aturan konjugasi, string pemutusan kata kerja, dll. Kemungkinan besar akan sama untuk masa hidup kita :)
Chris Cirefice
1
@ChrisCirefice ": tepat maksud saya.
Doc Brown
2

Bahkan walaupun hardcoding tampaknya baik-baik saja di sini, dan lebih baik daripada secara dinamis memuat file konfigurasi, saya masih akan merekomendasikan agar Anda benar-benar memisahkan data Anda (kamus kata kerja) dari algoritma . Anda dapat mengompilasinya langsung ke dalam aplikasi Anda dalam proses pembuatan.

Ini akan menghemat banyak hazzle dengan pemeliharaan daftar. Di VCS Anda, Anda dapat dengan mudah mengidentifikasi apakah komit mengubah algoritma, atau hanya memperbaiki bug konjugasi. Juga, daftar mungkin perlu ditambahkan di masa depan untuk kasus-kasus yang tidak Anda pertimbangkan. Terutama, jumlah 32 kata kerja tidak beraturan yang Anda hitung tampaknya tidak tepat. Sementara itu tampaknya mencakup yang umum digunakan, saya menemukan referensi ke 133 atau bahkan 350 di antaranya.

Bergi
sumber
Bergi, saya berencana memisahkan data dari algoritma. Apa yang Anda perhatikan tentang laskar Perancis - definisi irreguler paling disalahpahami. Apa yang saya maksudkan ketika saya katakan tidak beraturan adalah kata kerja yang tidak dapat 'dihitung', atau dikonjugasikan dari bentuk infinitifnya saja. Kata kerja tidak beraturan sama sekali tidak memiliki pola tertentu, dan oleh karena itu perlu konjugasinya terdaftar secara eksplisit (di bawah French.Verb.Conjugation.Irregular` misalnya). Secara teknis, kata kerja -irnya 'tidak teratur', tetapi sebenarnya memiliki pola konjugasi tetap :)
Chris Cirefice
0

Bagian yang penting adalah pemisahan perhatian. Bagaimana Anda mencapainya itu kurang relevan. yaitu Java baik-baik saja.

Terlepas dari bagaimana aturan diekspresikan, haruskah Anda perlu menambahkan bahasa perubahan aturan: berapa banyak kode dan file yang harus Anda edit?

Idealnya, menambahkan bahasa baru harus dimungkinkan dengan menambahkan file 'english.xml' atau yang baru 'EnglishRules mengimplementasikan objek ILanguageRules'. File teks (JSON / XML) memberi Anda keuntungan jika Anda ingin mengubahnya di luar siklus hidup build Anda, tetapi membutuhkan tata bahasa yang rumit, penguraian, dan akan lebih sulit untuk di-debug. File kode (Java) memungkinkan Anda mengekspresikan aturan yang rumit dengan cara yang lebih sederhana, tetapi membutuhkan pembangunan kembali.

Saya akan mulai dengan Java API sederhana di belakang antarmuka agnostik bahasa bersih - seperti yang Anda butuhkan dalam kedua kasus. Anda selalu dapat menambahkan implementasi antarmuka yang didukung oleh file XML nanti jika Anda mau, tapi saya tidak melihat kebutuhan untuk segera mengatasi masalah itu (atau pernah).

ptyx
sumber