Apa itu "Soft Coding"?


87

Di artikel ini oleh Alex Papadimoulis, Anda dapat melihat cuplikan ini:

private void attachSupplementalDocuments()
{
  if (stateCode == "AZ" || stateCode == "TX") {

    //SR008-04X/I are always required in these states
    attachDocument("SR008-04X");
    attachDocument("SR008-04XI");
  }

  if (ledgerAmnt >= 500000) {
    //Ledger of 500K or more requires AUTHLDG-1A
    attachDocument("AUTHLDG-1A");
  }

  if (coInsuredCount >= 5  && orgStatusCode != "CORP") {
    //Non-CORP orgs with 5 or more co-ins require AUTHCNS-1A
    attachDocument("AUTHCNS-1A");
  }
}

Saya benar-benar tidak mengerti artikel ini.

Saya mengutip:

Jika setiap aturan bisnis konstan disimpan dalam beberapa file konfigurasi, hidup akan jauh [lebih ( sic )] sulit bagi semua orang menjaga perangkat lunak: akan ada banyak file kode yang berbagi satu, file besar (atau, sebaliknya, banyak sekali file konfigurasi kecil); menyebarkan perubahan pada aturan bisnis tidak memerlukan kode baru, tetapi secara manual mengubah file konfigurasi; dan debugging jauh lebih sulit.

Ini adalah argumen yang menentang memiliki bilangan bulat konstan "500000" dalam file konfigurasi, atau "AUTHCNS-1A" dan konstanta string lainnya.

Bagaimana ini bisa menjadi praktik yang buruk?

Dalam cuplikan ini, "500000" bukan angka. Misalnya, tidak sama dengan:

int doubleMe(int a) { return a * 2;}

di mana 2, adalah angka yang tidak perlu diabstraksi. Penggunaannya jelas, dan itu tidak mewakili sesuatu yang dapat digunakan kembali nanti.

Sebaliknya, "500000" bukan sekadar angka. Ini nilai yang signifikan, nilai yang mewakili ide breakpoint dalam fungsionalitas. Nomor ini dapat digunakan di lebih dari satu tempat, tetapi bukan nomor yang Anda gunakan; itu adalah gagasan tentang batas / batas, di bawah mana satu aturan berlaku, dan di atasnya yang lain.

Bagaimana merujuknya dari file konfigurasi, atau bahkan #define, constatau apa pun yang disediakan bahasa Anda, lebih buruk daripada memasukkan nilainya? Jika nanti pada program, atau programmer lain, juga memerlukan garis batas itu, sehingga perangkat lunak membuat pilihan lain, Anda kacau (karena ketika itu berubah, tidak ada yang menjamin Anda bahwa itu akan berubah di kedua file). Itu jelas lebih buruk untuk debugging.

Selain itu, jika besok, pemerintah menuntut "Dari 5/3/2050, Anda perlu menambahkan AUTHLDG-122B alih-alih AUTHLDG-1A", konstanta string ini bukan konstanta string sederhana. Itu salah satu yang mewakili ide; itu hanya nilai saat ini dari ide itu (yang merupakan "hal yang Anda tambahkan jika buku besar di atas 500k").

Izinkan saya mengklarifikasi. Saya tidak mengatakan bahwa artikel itu salah; Saya tidak mengerti; mungkin itu tidak dijelaskan dengan baik (setidaknya untuk pemikiran saya).

Saya mengerti bahwa mengganti setiap string yang mungkin nilai literal atau numerik dengan variabel konstan, define, atau konfigurasi, tidak hanya tidak perlu, tetapi terlalu rumit, tetapi contoh khusus ini tampaknya tidak termasuk dalam kategori ini. Bagaimana Anda tahu bahwa Anda tidak akan membutuhkannya nanti? Atau orang lain dalam hal ini?


21
Mainkan puzzle: apa nama yang bagus untuk angka-angka itu? Saya pikir Anda akan menemukan bahwa salah satu nama tidak menambah nilai apa pun, atau menggambarkan semua kode yang sudah dijelaskan dan sering kali sambil menambahkan ambiguitas ("LedgerLimitForAuthDlg1A"?). Saya menemukan artikel brilian persis karena bagaimana relevan ini. Saya telah memelihara sistem yang telah menggunakan kedua pendekatan tersebut, dan saya dapat memberi tahu Anda bahwa aturan bisnis termasuk dalam kode - itu membuatnya lebih mudah untuk dilacak, dipelihara, dan dipahami. Ketika Anda menggunakan konfigurasi, Anda lebih baik membuatnya diperhitungkan - itu jauh lebih mahal.
Luaan

2
Konfigurasi harus disediakan untuk hal-hal yang perlu dikonfigurasi. Jika aturan bisnis tidak dapat dikonfigurasi secara umum, tetap menempatkan bit-bit itu dalam konfigurasi tidak akan memberi Anda apa-apa.
biziclop

Untuk bahasa tingkat lanjut yang sesuai, konfigurasi mengambil bentuk subrutin aktual dan bukan string.
Thorbjørn Ravn Andersen

Jawaban:


100

Penulis memperingatkan abstraksi prematur.

Garis tersebut if (ledgerAmt > 500000)terlihat seperti jenis aturan bisnis yang Anda harapkan untuk dilihat untuk sistem bisnis besar yang kompleks yang persyaratannya sangat kompleks namun tepat dan terdokumentasi dengan baik.

Biasanya persyaratan semacam itu adalah kasus luar biasa / tepi daripada logika yang dapat digunakan kembali. Persyaratan tersebut biasanya dimiliki dan dikelola oleh analis bisnis dan ahli materi pelajaran, bukan oleh insinyur

(Perhatikan bahwa 'kepemilikan' persyaratan oleh Analis Bisnis / pakar dalam kasus ini biasanya terjadi di mana pengembang yang bekerja di bidang spesialis tidak memiliki keahlian domain yang memadai; meskipun saya masih mengharapkan komunikasi / kerja sama penuh antara pengembang dan pakar domain untuk melindungi dari persyaratan ambigu atau ditulis dengan buruk.)

Ketika memelihara sistem yang persyaratannya dikemas penuh dengan kasus tepi dan logika yang sangat kompleks, biasanya tidak ada cara untuk mengabstraksi logika tersebut atau membuatnya lebih dapat dipertahankan; upaya untuk mencoba membangun abstraksi dapat dengan mudah menjadi bumerang - tidak hanya menghasilkan waktu yang terbuang, tetapi juga menghasilkan kode yang kurang dapat dipelihara.

Bagaimana merujuknya dari file konfigurasi, atau bahkan #define, const atau apa pun yang disediakan bahasa Anda, lebih buruk daripada memasukkan nilainya? Jika nanti pada program, atau programmer lain, juga memerlukan garis batas itu, sehingga perangkat lunak membuat pilihan lain, Anda kacau (karena ketika itu berubah, tidak ada yang menjamin Anda bahwa itu akan berubah di kedua file). Itu jelas lebih buruk untuk debugging.

Jenis kode ini cenderung dijaga oleh fakta bahwa kode itu sendiri mungkin memiliki pemetaan satu-ke-satu dengan persyaratan; yaitu ketika pengembang tahu bahwa 500000angka tersebut muncul dua kali dalam persyaratan, pengembang itu juga tahu bahwa itu muncul dua kali dalam kode.

Pertimbangkan skenario lain (yang kemungkinannya sama) di mana 500000muncul di banyak tempat dalam dokumen persyaratan, tetapi Ahli Subjek memutuskan untuk hanya mengubah salah satunya; di sana Anda memiliki risiko yang lebih buruk lagi bahwa seseorang yang mengubah constnilainya mungkin tidak menyadari bahwa 500000itu digunakan untuk mengartikan hal-hal yang berbeda - sehingga pengembang mengubahnya di satu-satunya tempat ia menemukannya dalam kode, dan akhirnya merusak sesuatu yang mereka tidak menyadari bahwa mereka telah berubah.

Skenario ini banyak terjadi pada perangkat lunak hukum / keuangan yang dipesan lebih dahulu (mis. Logika kutipan asuransi) - orang yang menulis dokumen semacam itu bukanlah insinyur, dan mereka tidak memiliki masalah menyalin + menempelkan seluruh bidak dari spesifikasi, memodifikasi beberapa kata / angka, tetapi meninggalkan sebagian besar sama.

Dalam skenario itu, cara terbaik untuk menangani persyaratan salin-tempel adalah dengan menulis kode salin-rekat, dan membuat kode itu terlihat sama dengan persyaratan (termasuk mengode semua data) sebaik mungkin.

Kenyataan dari persyaratan tersebut adalah bahwa mereka biasanya tidak tinggal salin + tempel lama, dan nilai-nilai kadang-kadang berubah secara teratur, tetapi mereka sering tidak berubah bersama-sama, jadi cobalah untuk merasionalisasi atau abstrak persyaratan tersebut keluar atau menyederhanakan mereka dengan cara apa pun akhirnya menciptakan lebih banyak sakit kepala pemeliharaan daripada hanya menerjemahkan persyaratan kata demi kata menjadi kode.


28
Domain Specific Language (DSL) dapat menjadi cara yang baik untuk membuat kode lebih dibaca seperti dokumen persyaratan.
Ian

13
Keuntungan lain dari DSL adalah yang juga membuatnya lebih sulit untuk secara tidak sengaja menggabungkan aplikasi, presentasi, atau logika persistensi dengan aturan bisnis.
Erik Eidt

16
Berpikir bahwa aplikasi Anda cukup istimewa untuk menjamin DSL sendiri biasanya adalah keangkuhan.
brian_o

8
Those requirements are typically owned and maintained by business analysts and subject matter experts, rather than by engineersyang tidak selalu merupakan ide yang bagus. Kadang-kadang tindakan mengubah persyaratan tersebut menjadi kode akan mengungkapkan kasus sudut di mana persyaratan tersebut tidak didefinisikan dengan baik atau didefinisikan sedemikian rupa sehingga bertentangan dengan kepentingan bisnis. Jika analis bisnis dan pengembang dapat bekerja sama untuk mencapai tujuan bersama, maka banyak masalah dapat dihindari.
kasperd

4
@BenCottrell Saya tidak menyarankan untuk mengubah aturan untuk membuatnya lebih mudah untuk menulis perangkat lunak. Tetapi ketika Anda memiliki banyak persyaratan dalam aturan, sangat mungkin bahwa beberapa interaksi antara mereka tidak terjawab ketika mendefinisikan aturan di tempat pertama. Tetapi ketika Anda mengubah spesifikasi menjadi kode, pengembang terikat untuk memperhatikan bahwa ada kemungkinan interaksi antara kondisi tersebut. Pada titik ini adalah mungkin bahwa pengembang menemukan bahwa interpretasi yang ketat dari spesifikasi mengarah pada harga yang tidak disengaja yang akan memungkinkan pelanggan untuk memainkan sistem.
kasperd

44

Artikel ini memiliki poin bagus. Bagaimana bisa menjadi praktik yang buruk untuk mengekstrak konstanta ke file konfigurasi? Ini bisa menjadi praktik buruk jika menyulitkan kode. Memiliki nilai langsung dalam kode jauh lebih sederhana daripada harus membacanya dari file konfigurasi, dan kode yang ditulis mudah diikuti.

Selain itu, besok, pemerintah menyatakan "Dari 5/3/2050, Anda perlu menambahkan AUTHLDG-122B, bukan AUTHLDG-1A".

Ya, maka Anda mengubah kode. Maksud artikel ini adalah tidak lebih rumit untuk mengubah kode daripada mengubah file konfigurasi.

Pendekatan yang dijelaskan dalam artikel tidak berskala jika Anda mendapatkan logika yang lebih kompleks, tetapi intinya adalah bahwa Anda harus membuat penilaian, dan kadang-kadang solusi paling sederhana adalah yang terbaik.

Bagaimana Anda tahu bahwa Anda tidak akan membutuhkannya nanti? Atau orang lain dalam hal ini?

Inilah inti dari prinsip YAGNI. Jangan mendesain untuk masa depan yang tidak diketahui yang mungkin berubah sama sekali berbeda, desain untuk saat ini. Anda benar bahwa jika nilai 500000 digunakan beberapa tempat dalam program ini tentu saja harus diekstraksi menjadi konstanta. Tapi ini tidak terjadi dalam kode yang dimaksud.

Softcoding sebenarnya adalah pertanyaan pemisahan masalah . Anda informasi kode lunak yang Anda tahu mungkin berubah secara independen dari logika aplikasi inti. Anda tidak akan pernah mengubah kode string koneksi ke database, karena Anda tahu itu mungkin berubah secara independen dari logika aplikasi dan Anda perlu membedakannya untuk lingkungan yang berbeda. Dalam aplikasi web kami ingin memisahkan logika bisnis dari template html dan style sheet, karena mereka dapat berubah secara independen dan bahkan diubah oleh orang yang berbeda.

Tetapi dalam kasus dalam contoh kode, string dan angka yang di-hardcod merupakan bagian integral dari logika aplikasi. Dapat dibayangkan bahwa satu file dapat mengubah namanya karena beberapa perubahan kebijakan di luar kendali Anda, tetapi dapat dibayangkan bahwa kami perlu menambahkan cabang-baru yang memeriksa kondisi yang berbeda. Mengekstraksi nama dan nomor file benar-benar merusak kohesi dalam kasus ini.


4
Seringkali jauh lebih rumit untuk mengubah kode daripada file konfigurasi. Anda mungkin membutuhkan pengembang dan siklus sistem / rilis untuk yang pertama, sedangkan yang terakhir hanya membutuhkan perubahan nomor dalam sebuah kotak di UI konfigurasi ramah.
OrangeDog

6
@OrangeDog Ya, begitulah tampilannya pada awalnya. Tapi jika Anda melakukan hal-hal seperti ini, konfigurasi UI akan menjadi apa-apa tapi ramah, dengan ratusan benar-benar berarti teks-kotak yang meminta Anda untuk siapa yang tahu apa yang. Dan sekarang Anda harus membangun UI, dan mendokumentasikannya. Pikiran Anda, itu tidak berarti konfigurasi tidak pernah cara yang baik untuk pergi - ada kasus di mana itu benar-benar pilihan yang tepat. Tetapi tidak dalam salah satu contoh dalam artikel. Dan kapan terakhir kali undang-undang mengubah nomornya? Terakhir kali aturan PPN berubah di sini, kami harus mengulang semua perhitungan.
Luaan

2
@OrangeDog: Anda mengasumsikan, di sini, bahwa konfigurasi perangkat lunak memberi Anda kait yang diperlukan untuk pemeriksaan yang perlu Anda lakukan. Perhatikan bagaimana di OP masing-masing ifdidasarkan pada variabel yang berbeda! Jika variabel yang Anda butuhkan tidak dapat diakses dari konfigurasi, Anda tetap harus memodifikasi perangkat lunak.
Matthieu M.

2
@OrangeDog jadi Anda menyarankan bahwa harus ada perubahan signifikan pada logika aplikasi perangkat lunak, tanpa siklus dev / qa / release dan pengujian yang sesuai?
NPSF3000

3
@OrangeDog: OK, Anda menggunakan YAML untuk mengkonfigurasi logika pada contoh. Karena logika menyertakan aturan kondisional, Anda menemukan cara untuk mewakili kondisional ini di YAML. Selamat, Anda telah menemukan kembali Python. Mengapa tidak menulis seluruh aplikasi dengan Python?
JacquesB

26

Artikel selanjutnya membahas tentang 'Enterprise Rule Engine's yang mungkin merupakan contoh yang lebih baik dari apa yang dia bantah.

Logikanya adalah bahwa Anda dapat menggeneralisasi ke titik di mana konfigurasi Anda menjadi sangat rumit sehingga mengandung bahasa pemrograman sendiri.

Misalnya, kode negara untuk mendokumentasikan pemetaan dalam contoh dapat dipindahkan ke file konfigurasi. Tetapi Anda kemudian perlu mengekspresikan hubungan yang kompleks.

<statecode id="AZ">
    <document id="SR008-04X"/>
    <document id="SR008-04XI"/>
</statecode>

Mungkin Anda juga akan memasukkan jumlah buku besar?

<statecode id="ALL">
    <document id="AUTHLDG-1A" rule="ledgerAmt >= 50000"/>
</statecode>

Segera Anda menemukan bahwa Anda memprogram dalam bahasa baru yang Anda temukan dan menyimpan kode itu dalam file konfigurasi yang tidak memiliki sumber atau perubahan kontrol.

Perlu dicatat bahwa artikel ini berasal dari 2007 ketika hal semacam ini merupakan pendekatan umum.

Saat ini kami mungkin akan menyelesaikan masalah dengan ketergantungan injeksi (DI). Yaitu, Anda akan memiliki 'kode keras'

InvoiceRules_America2007 : InvoiceRules

yang akan Anda ganti dengan kode keras, atau lebih dapat dikonfigurasi

InvoiceRules_America2008 : InvoiceRules

ketika persyaratan hukum atau bisnis berubah.


4
Mungkin Anda harus mendefinisikan "DI". Dan mungkin menjelaskan sedikit lebih banyak.
Basil Bourque

9
Mengapa file itu tidak ada dalam sistem kontrol sumber?
JDługosz

2
Jika itu spesifik untuk klien, apakah versi kode memiliki banyak ifpernyataan untuk memberikan nilai yang berbeda untuk setiap klien? Itu terdengar seperti sesuatu yang harus ada dalam file konfigurasi. Berada dalam satu jenis file atau lainnya, semuanya sama, bukan alasan untuk tidak mengontrol / melacak / membuat cadangan file. @ewan tampaknya mengatakan bahwa file DSL tidak dapat disimpan sebagai bagian dari proyek untuk beberapa alasan, bahkan ketika aset non-kode seperti gambar dan file suara dan dokumentasi tentu adalah .
JDługosz

2
Anda harus benar-benar memperbaiki nilai "50000" dari XML Anda dan meletakkannya di file konfigurasi terpisah, bukan? ... dan itu seharusnya 500000, omong-omong.
Wildcard

1
@ jdlugosz konsep ERE adalah Anda membeli sistem dan kemudian mengkonfigurasinya untuk kebutuhan Anda. mungkin karena para dev internal berkompetisi dengan sistem 'fleksibel' ini, mereka akan mencoba meniru mereka. mengubah kontrol konfigurasi, bahkan dalam sistem dari perusahaan besar seperti IBM sering menjadi renungan. Titik penjualan adalah perubahan cepat
Ewan

17

Sebaliknya, "500000" bukan sekadar angka. Ini nilai yang signifikan, nilai yang mewakili ide breakpoint dalam fungsionalitas. Angka ini dapat digunakan di lebih dari satu tempat, tetapi itu bukan angka yang Anda gunakan, ini adalah gagasan tentang batas / batas, di bawah mana satu aturan berlaku, dan di atas yang lainnya.

Dan itu diungkapkan dengan memiliki (dan saya bisa berpendapat bahwa bahkan komentar itu berlebihan):

 if (ledgerAmnt >= 500000) {
    //Ledger of 500K or more requires AUTHLDG-1A
    attachDocument("AUTHLDG-1A");
  }

Ini hanya mengulangi apa yang dilakukan kode:

LEDGER_AMOUNT_REQUIRING_AUTHLDG1A=500000
if (ledgerAmnt >= LEDGER_AMOUNT_REQUIRING_AUTHLDG1A) {
    //Ledger of 500K or more requires AUTHLDG-1A
    attachDocument("AUTHLDG-1A");
}

Perhatikan bahwa penulis mengasumsikan bahwa arti 500000 terkait dengan aturan ini; itu bukan nilai yang mungkin atau akan digunakan kembali di tempat lain:

Satu-satunya perubahan aturan bisnis yang dapat dilakukan oleh Soft Coding sebelumnya adalah perubahan dalam jumlah buku besar yang memerlukan formulir AUTHLDG-1A. Perubahan aturan bisnis lainnya akan membutuhkan lebih banyak pekerjaan - konfigurasi, dokumentasi, kode, dll

Poin utama artikel ini, dalam pandangan saya, adalah bahwa kadang-kadang angka hanyalah angka: itu tidak memiliki arti lain selain apa yang disampaikan dalam kode dan tidak mungkin digunakan di tempat lain. Oleh karena itu, canggung meringkas apa yang dilakukan kode (sekarang) dalam nama variabel hanya demi menghindari nilai-nilai hard-kode adalah pengulangan yang tidak perlu di terbaik.


2
Jika Anda memperkenalkan konstanta LEDGER_AMOUNT_REQUIRING_AUTHLDG1A, Anda tidak akan menulis komentar ke dalam kode lagi. Komentar tidak dikelola dengan baik oleh programmer. Jika jumlahnya berubah, ifkondisi dan komentar akan keluar dari sinkronisasi. Sebaliknya, konstanta LEDGER_AMOUNT_REQUIRING_AUTHLDG1Atidak pernah keluar dari sinkronisasi dengan dirinya sendiri dan ia menjelaskan tujuannya tanpa komentar yang tidak perlu.
ZeroOne

2
@ZeroOne: Kecuali jika aturan bisnis berubah menjadi "Buku besar 500K atau lebih membutuhkan AUTHLDG-1A dan AUTHLDG-2B", sangat mungkin bahwa orang yang menambahkan attachDocument("AUTHLDG-2B");saluran akan gagal memperbarui nama konstan pada saat yang sama. Dalam hal ini, saya pikir kodenya cukup jelas tanpa komentar atau variabel explainer. (Meskipun mungkin masuk akal untuk memiliki konvensi untuk menunjukkan bagian yang sesuai dari dokumen persyaratan bisnis melalui komentar kode. Di bawah konvensi semacam itu, sebuah komentar kode yang melakukan hal itu akan sesuai di sini.)
ruakh

@ruakh, OK, maka saya akan refactor yang dipanggil LEDGER_AMOUNT_REQUIRING_ADDITIONAL_DOCUMENTS(yang mungkin seharusnya saya lakukan di tempat pertama). Saya juga terbiasa memasukkan ID persyaratan bisnis ke dalam pesan commit Git, bukan ke dalam kode sumber.
ZeroOne

1
@Eroero: Tetapi untuk AUTHLDG-3C jumlah buku besar sebenarnya maksimum . Dan untuk AUTHLDG-4D jumlah buku besar yang sesuai tergantung pada negara. (Apakah Anda mengerti maksudnya? Untuk jenis kode ini, Anda ingin kode Anda mencerminkan aturan bisnis, bukan beberapa upaya abstraksi dari aturan bisnis, karena tidak ada alasan untuk mengharapkan evolusi aturan bisnis sejalan dengan abstraksi yang telah Anda adopsi.)
ruakh

2
Secara pribadi, saya tidak keberatan untuk memasukkan angka ajaib dalam kode, saya keberatan menyusun kode sehingga perlu komentar ini. Jika itu saya, saya akan membuat setiap dokumen contoh enum dengan attachIfNecessary()metode sendiri dan hanya mengulangi semuanya.
David Moles

8

Jawaban lainnya benar, dan bijaksana. Tapi ini jawaban singkat dan manis saya.

  Rule/value          |      At Runtime, rule/value…
  appears in code:    |   …Is fixed          …Changes
----------------------|------------------------------------
                      |                 |
  Once                |   Hard-code     |   Externalize
                      |                 |   (soft-code)
                      |                 |
                      |------------------------------------
                      |                 |
  More than once      |   Soft-code     |   Externalize
                      |   (internal)    |   (soft-code)
                      |                 |
                      |------------------------------------

Jika aturan dan nilai khusus muncul di satu tempat dalam kode, dan tidak berubah selama runtime, maka hard-code seperti yang ditunjukkan dalam pertanyaan.

Jika aturan atau nilai khusus muncul di lebih dari satu tempat dalam kode, dan tidak berubah selama runtime, maka kode lunak. Soft-coding untuk suatu aturan mungkin saya mendefinisikan kelas / metode tertentu atau menggunakan pola Builder . Untuk nilai, soft-coding dapat berarti mendefinisikan konstanta tunggal atau enum untuk nilai yang akan digunakan di seluruh kode Anda.

Jika aturan atau nilai khusus dapat berubah selama runtime, maka Anda harus mengeksternalisasi mereka. Ini biasanya dilakukan dengan memperbarui nilai dalam database. Atau perbarui nilai dalam memori secara manual oleh pengguna yang memasukkan data. Hal ini juga dilakukan dengan menyimpan nilai-nilai dalam file teks (XML, JSON, teks biasa, apa pun) yang berulang kali dipindai untuk perubahan tanggal-waktu modifikasi file.


1
Saya suka jawaban Anda, tetapi saya pikir Anda juga harus mempertimbangkan apakah itu berubah saat implementasi. Hal ini terutama relevan jika masalahnya adalah produk yang akan digunakan di banyak organisasi yang mungkin, misalnya, memiliki aturan berbeda mengenai apakah seorang penyelia perlu menyetujui pengembalian uang atas X, dll.
Bloke Down The Pub

Setuju dengan jawaban ini dan komentar tentang implementasi. Hal-hal yang saya kerjakan diimplementasikan oleh banyak organisasi, dan banyak dari mereka memiliki nilai-nilai berbeda yang diperlukan. Kami cenderung menyimpan 'pengaturan' ini dalam basis data alih-alih file konfigurasi, tetapi prinsipnya adalah bahwa kami tidak ingin membuat build yang berbeda dari perangkat lunak kami untuk setiap perusahaan yang mengimplementasikannya (kemudian ulangi build yang berbeda itu setiap kali mereka upgrade) .
RosieC

7

Ini adalah jebakan yang kita jatuhi ketika kita menggunakan masalah mainan dan kemudian hanya mengajukan solusi stroberi , ketika kita mencoba menggambarkan masalah sebenarnya.

Pada contoh yang diberikan, tidak ada bedanya apakah nilai yang diberikan hardcoded sebagai nilai inline, atau didefinisikan sebagai const.

Ini adalah kode di sekitarnya yang akan membuat contoh pemeliharaan dan pengkodean horor. Jika ada yang tidak ada kode sekitarnya, maka potongan-baik saja, setidaknya di lingkungan refactoring konstan. Dalam lingkungan di mana refactoring cenderung tidak terjadi, pemelihara kode itu sudah mati, karena alasan yang akan segera menjadi jelas.

Lihat, jika ada kode di sekitarnya, maka hal-hal buruk jelas terjadi.

Hal buruk pertama adalah bahwa nilai 50000 digunakan untuk nilai lain di suatu tempat, katakanlah, jumlah buku besar di mana tarif pajak berubah di beberapa negara ... maka ketika perubahan terjadi, pengelola tidak memiliki cara untuk mengetahui, ketika ia menemukan mereka dua contoh kode 50.000, apakah artinya 50k yang sama, atau 50k yang sama sekali tidak terkait. Dan haruskah Anda juga mencari 49999 dan 50001, kalau-kalau ada orang yang menggunakannya juga? Ini bukan panggilan untuk plonk variabel-variabel itu dalam file konfigurasi layanan terpisah: tetapi hardcoding mereka sebaris jelas juga salah. Sebagai gantinya, mereka harus berupa konstanta, didefinisikan dan dicakup dalam kelas atau file di mana mereka digunakan. Jika dua contoh 50k menggunakan konstanta yang sama, maka mereka kemungkinan mewakili pembatasan legislatif yang sama; jika tidak, mereka mungkin tidak; dan bagaimanapun, mereka akan memiliki nama,

Nama file diteruskan ke fungsi - attachDocument () - yang menerima nama file dasar sebagai string, tanpa path atau ekstensi. Nama file pada dasarnya adalah kunci asing ke beberapa sistem file, atau basis data, atau dari mana pun attachDocument () mendapatkan file. Tetapi string tidak memberi tahu Anda tentang hal ini - berapa banyak file yang ada? Apa jenis file mereka? Bagaimana Anda tahu, ketika membuka pasar baru, apakah Anda perlu memperbarui fungsi ini? Ke hal apa mereka bisa dilampirkan? Pemelihara dibiarkan sepenuhnya dalam kegelapan, dan semua yang dimilikinya adalah string, yang dapat muncul beberapa kali dalam kode dan berarti hal yang berbeda setiap kali muncul. Di satu tempat, "SR008-04X" adalah kode cheat. Di lain, itu adalah perintah untuk memesan empat roket pendorong SR008. Ini dia' sa nama file? Apakah ini terkait? Seseorang baru saja mengubah fungsi itu untuk menyebutkan file lain, "CLIENT". Maka Anda, pengelola yang buruk, telah diberi tahu bahwa file "KLIEN" perlu diganti namanya menjadi "PELANGGAN". Tetapi string "CLIENT" muncul 937 kali dalam kode ... di mana Anda bahkan mulai mencari?

Masalah mainannya adalah bahwa semua nilainya tidak biasa dan dapat dijamin secara unik untuk menjadi unik dalam kode. Bukan "1" atau "10" tetapi "50.000". Bukan "klien" atau "laporkan" tetapi "SR008-04X".

The strawman adalah bahwa satu-satunya cara lain untuk mengatasi masalah konstanta impenetrably buram adalah untuk sarang mereka kabur ke file konfigurasi dari beberapa layanan yang tidak terkait.

Bersama-sama, Anda dapat menggunakan dua kesalahan ini untuk membuktikan argumen apa pun yang benar.


2
Bukan masalah mainan, bukan strawman. Ini adalah sesuatu yang akan Anda lihat sepanjang waktu dalam aplikasi bisnis semacam ini. Tidak ada "pembukaan ke pasar baru", tidak ada penggunaan kembali dari nomor yang sama (setelah semua, itu akan memberikan arti lain pula) dan dalam hal apapun, artikel itu mengatakan tidak menentang KERING - jika ada dua ketergantungan pada nilai, itu akan dipindahkan ke metode atau konstanta. Perlihatkan contoh bagaimana konstanta-konstanta itu (dari pengaturan konfigurasi, tidak terlalu penting) harus dinamai, dan di mana mereka harus disimpan dengan cara yang bukti masa depan dan lebih jelas daripada kode.
Luaan

4
Contohnya tidak rusak karena masalah mainan. Kode di sekitarnya akan selalu mengerikan karena aturan bisnis yang harus dijalankan oleh perangkat lunak mengerikan . Upaya untuk melangkahi tantangan mendasar ini dengan mesin aturan dan DSL dan yang lainnya sering menunda-nunda programer , karena menyelesaikan masalah CS lebih menyenangkan daripada menyelesaikan seluk-beluk formulir pajak. Upaya mencapai 'keanggunan' sering kali merupakan tugas bodoh karena tugas utama perangkat lunak adalah memodelkan bencana yang rumit.
whatsisname

Aturan bisnis mungkin horor, tetapi itu sendiri bukan alasan untuk menulis kode prosedural yang biasa-biasa saja ini. (Saya cenderung setuju dengan Papadimoulis bahwa lebih mudah untuk memodelkan dan mempertahankan aturan dalam kode daripada di konfigurasi, saya hanya berpikir itu harus kode yang lebih baik.) Masalah KERING yang saya lihat bukan angka ajaib, itu yang diulang if (...) { attachDocument(...); }.
David Moles

2

Ada beberapa masalah dalam hal ini.

Salah satu masalah adalah apakah sebuah mesin aturan harus dibuat untuk membuat semua aturan mudah dikonfigurasi di luar program itu sendiri. Jawaban dalam kasus yang mirip dengan ini paling sering tidak. Aturan akan berubah dengan cara aneh yang sulit diprediksi yang berarti bahwa mesin aturan harus diperpanjang setiap kali ada perubahan.

Masalah lain adalah bagaimana menangani aturan-aturan ini dan perubahannya dalam kontrol versi Anda. Solusi terbaik di sini adalah dengan membagi aturan menjadi kelas untuk setiap aturan.

Yang memungkinkan setiap aturan untuk memiliki validitasnya sendiri, beberapa peraturan berubah setiap tahun, beberapa perubahan tergantung pada kapan izin telah diberikan atau faktur dikeluarkan. Aturan itu sendiri berisi cek versi mana yang harus diterapkan.

Juga karena konstanta bersifat pribadi itu tidak dapat disalahgunakan di tempat lain dalam kode.

Kemudian miliki daftar semua aturan dan terapkan daftar itu.

Masalah selanjutnya adalah bagaimana menangani konstanta. 500000 mungkin terlihat tidak mencolok tetapi harus sangat hati-hati untuk memastikannya dikonversi dengan benar. Jika ada aritmatika floating point diterapkan itu mungkin dikonversi ke 500.000,00001 sehingga perbandingan dengan 500.000,00000 mungkin gagal. Atau 500000 lebih buruk selalu berfungsi seperti yang dimaksudkan, tetapi entah bagaimana 565000 gagal ketika dikonversi. Pastikan konversi itu eksplisit dan dibuat oleh Anda bukan oleh tebak kompiler. Seringkali ini dilakukan dengan mengonversinya ke BigInteger atau BigDecimal sebelum digunakan.


2

Meskipun tidak secara langsung disebutkan dalam pertanyaan, saya ingin mencatat bahwa yang penting adalah tidak mengubur logika bisnis dalam kode.

Kode, seperti contoh di atas, yang menyandikan persyaratan bisnis yang ditentukan secara eksternal harus benar-benar hidup di bagian berbeda dari pohon sumber, mungkin dinamai businesslogicatau sesuatu yang serupa, dan harus berhati-hati untuk memastikan bahwa itu hanya menyandikan persyaratan bisnis secara sederhana, mudah dibaca dan seringkas mungkin, dengan boilerplate minimum dan dengan komentar yang jelas dan informatif.

Seharusnya tidak dicampur dengan kode "infrastruktur" yang mengimplementasikan fungsi yang diperlukan untuk menjalankan logika bisnis, seperti, katakanlah, implementasi attachDocument()metode dalam contoh, atau misalnya UI, pencatatan atau kode basis data secara umum. Sementara satu cara untuk menegakkan pemisahan ini adalah dengan "kode lunak" semua logika bisnis dalam file konfigurasi, ini jauh dari satu-satunya metode (atau yang terbaik).

Kode logika bisnis seperti itu juga harus ditulis dengan cukup jelas sehingga, jika Anda menunjukkannya kepada pakar domain bisnis tanpa keterampilan pengkodean, mereka akan dapat memahaminya. Paling tidak, jika dan ketika persyaratan bisnis berubah, kode yang mengkodekannya harus cukup jelas sehingga bahkan seorang programmer baru tanpa familier dengan basis kode harus dapat dengan mudah menemukan, meninjau dan memperbarui logika bisnis, dengan asumsi bahwa tidak diperlukan fungsionalitas baru secara kualitatif.

Idealnya, kode tersebut juga akan ditulis dalam bahasa khusus domain untuk menegakkan pemisahan antara logika bisnis dan infrastruktur yang mendasarinya, tetapi itu mungkin tidak perlu rumit untuk aplikasi in-house dasar. Yang mengatakan, jika Anda misalnya menjual perangkat lunak kepada banyak klien yang masing-masing memerlukan seperangkat aturan bisnis kustom mereka sendiri, bahasa scripting khusus domain sederhana (mungkin misalnya berdasarkan pada kotak pasir Lua ) mungkin saja masalahnya.


Inilah yang saya pikirkan !!! Ketika logika terkubur dalam-dalam kode, bagaimana pakar domain / subjek atau pengguna bisnis dapat melihat nilai-nilai dan logika yang digunakan untuk memastikan mereka benar, dan mendiagnosis perilaku sistem? Satu hal yang dilakukan file konfigurasi adalah membuat pengaturannya terlihat . Harus ada beberapa cara untuk mempromosikan visibilitas aturan bisnis - bahkan jika itu membuat pengkodean "lebih sulit". Saya dapat menerima kelas tipis atau serangkaian kelas yang melakukan pekerjaan itu, tanpa campur aduk dalam keprihatinan lain - selama pengguna bisnis memiliki sarana untuk mengakses dan memahaminya.
ErikE
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.