Apakah ini merupakan pelanggaran terhadap Prinsip Terbuka-Tertutup untuk memperbarui konstanta yang mewakili nilai dunia nyata?

10

Saya memiliki kelas yang menghitung pendapatan tahunan bersih pekerja. Ini memiliki konstanta yang mewakili persentase pajak. Tetapi suatu hari tarif pajak telah berubah, jadi saya perlu memperbaiki kodenya.

Apakah tindakan memperbaiki konstanta ini menunjukkan pelanggaran terhadap Prinsip Terbuka-Tertutup , karena mendalilkan bahwa suatu kelas harus ditutup untuk modifikasi?

Analisis Paradisys
sumber
10
Perangkat lunak berubah karena dunia nyata berubah. Di sisi lain, membuat persentase pajak suatu konstanta bukanlah pelanggaran terhadap Prinsip Terbuka-Tertutup karena hanya merupakan hal yang bodoh untuk dilakukan. Persentase pajak adalah barang yang jelas-jelas dapat diubah yang harus diikat pada waktu pelaksanaan.
Richard Chambers
4
Saya sepenuhnya setuju dengan Richard. Jika Anda harus mengubah kode untuk memperbaiki "konstan" ini, OCP adalah masalah Anda yang paling kecil.
Robert Harvey
3
Apa yang merupakan pelanggaran OCP sangat subyektif dan semuanya agak usang pula (karena warisan implementasi bukan praktik terbaik lagi). Ini adalah pertanyaan umum di mana Anda harus menebak apa yang dipikirkan orang yang mengajukan pertanyaan.
Robert Bräutigam
2
@DocBrown: apa yang merupakan "persyaratan baru"? Anda tunjukkan saya beberapa kode, saya bisa tunjukkan persyaratan baru yang pasti akan membutuhkan perubahan kode, terlepas dari bagaimana OCP menyesuaikan Anda membuatnya. Jadi kembali ke pertanyaan: Jika pengembang bertanya kepada pakar bisnis tentang hal itu, dan tidak ada harapan tarif pajak berubah lebih dari sekali setiap beberapa tahun, tidak ada gunanya membuatnya dapat dikonfigurasi atau disuntikkan. Tetap sederhana dan bersiaplah untuk apa yang Anda ketahui . Dan untuk hal-hal itu, tentu saja, buatlah itu di luar kelas. Jadi itu tergantung .
Robert Bräutigam
1
@ RobertBräutigam: maksud saya adalah, ada IMHO tidak ada yang namanya "OCP conform", hanya ada "OCP conform dalam konteks kategori persyaratan tertentu". Pasti ada beberapa subjektivitas kategori mana yang harus "komponen sesuai OCP". Tetapi dalam kasus yang dijelaskan dalam pertanyaan ini, seperti yang saya pahami, persyaratan yang berubah sudah diidentifikasi, sehingga "kelas penghitungan pendapatan" ini jelas tidak mematuhi OCP dalam konteks persyaratan khusus ini.
Doc Brown

Jawaban:

14

OCP dapat dipahami dengan lebih baik ketika memikirkan kelas atau komponen yang disediakan oleh vendor A di semacam perpustakaan kotak hitam, untuk penggunaan oleh pengguna B, C, dan D (perhatikan ini hanyalah model mental yang saya gunakan untuk kejelasan, tidak masalah jika dalam kenyataannya satu-satunya pengguna kelas adalah A sendiri).

Jika B, C dan D dapat menggunakan atau menggunakan kembali kelas yang disediakan untuk kasus penggunaan yang berbeda, tanpa perlu modifikasi kode sumber perpustakaan, maka komponen memenuhi OCP ( sehubungan dengan kategori kasus penggunaan ). Ada berbagai cara untuk mencapai ini, seperti

  • membuat kelas bisa diwariskan (biasanya dalam hubungannya dengan pola metode templat atau pola strategi)

  • dengan memberikan "titik injeksi" untuk injeksi ketergantungan

  • dengan memberikan parameter konfigurasi untuk kelas atau komponen (misalnya, dengan memiliki parameter konstruktor "persentase pajak", seperti dalam kasus Anda, atau dengan menggunakan beberapa mekanisme konfigurasi lainnya)

  • mungkin cara lain, tergantung pada bahasa pemrograman atau ekosistem

Contoh-contoh khas yang Anda temukan dalam buku teks sering kali dari tipe pertama atau kedua (saya kira karena di mata penulis buku itu, tipe ketiga terlalu sepele untuk disebutkan).

Seperti yang Anda lihat, ini tidak ada hubungannya dengan melarang perubahan kode sumber oleh vendor A (seperti untuk memperbaiki bug, optimasi atau menambahkan fitur baru dengan cara yang kompatibel dengan mundur), yang sangat tidak terkait dengan OCP. OCP adalah tentang bagaimana A mendesain antarmuka dan rincian komponen dalam lib, sehingga skenario penggunaan kembali yang berbeda (seperti bahasa dengan tarif pajak yang berbeda) tidak secara otomatis mendorong persyaratan untuk perubahan.

Jadi, terlepas dari apa yang orang lain katakan kepada Anda di sini, jawabannya jelas "ya" , itu akan menjadi pelanggaran terhadap OCP.

EDIT: tampaknya di antara seseorang menulis posting blog rinci tentang topik ini. Meskipun sebagian dari kata-kata itu bisa saja lebih baik (seperti yang ditunjukkan Derek Elkins), tampaknya penulis pada umumnya memiliki pandangan yang sama bahwa "memenuhi OCP" bukanlah properti absolut, tetapi sesuatu yang hanya dapat dievaluasi dalam konteks tertentu kategori perubahan persyaratan.

Doc Brown
sumber
OK, jadi OCP adalah tentang menyediakan perilaku yang dapat diperluas untuk berbagai kasus penggunaan dengan satu dari tiga berarti Anda telah terdaftar, bukan? Tetapi bagaimana jika contoh OP menyiratkan bahwa sesuatu yang fundamental akan berubah? Saya tidak tahu dari negara mana OP berasal, tetapi dalam tarif pajak negara saya adalah sesuatu yang tidak sering berubah. Itu adalah contoh yang buruk, tapi mungkin itu sengaja diekstraksi dalam sebuah konstanta, untuk menekankan intinya. Saya cukup yakin itu tidak dimaksudkan untuk dapat dikonfigurasi atau diperpanjang. Jadi mungkin pertanyaannya adalah tentang "ini tidak ada hubungannya dengan melarang perubahan kode sumber oleh vendor A" bagian.
Vadim Samokhin
Setidaknya saya memahaminya seperti itu. Orang miskin yang menghapus jawaban yang diterimanya melakukan itu, kurasa. Anda telah melihatnya dari sudut yang sedikit berbeda - Saya mengerti maksud Anda dan setuju dengannya. Tapi sepertinya komentar paling bijak diberikan oleh @Robert Bräutigam. Sampai sekarang saya belum menyadari bahwa OCP itu subjektif.
Vadim Samokhin
1
Saya kira jika saya pernah ditanya pertanyaan yang sama, ada satu pertanyaan yang harus saya ajukan sebagai balasan: "apakah perilaku itu seharusnya diperluas atau dikonfigurasi, entah bagaimana?". Jika ya - daripada modifikasi langsung dari kelas itu sendiri merupakan pelanggaran OCP. Jika tidak - selain OCP sama sekali tidak berlaku dalam situasi itu.
Vadim Samokhin
1
@Zapadlo: Saya pikir jika komponen memenuhi OCP untuk kelas persyaratan tidak terlalu subyektif - itu cukup jelas dalam kebanyakan kasus jika persyaratan baru memerlukan modifikasi kode sumber komponen, atau jika komponen mendukung persyaratan ini ". Pendekatan yang mungkin untuk menerapkannya tidak terbatas pada 3 cara pertama yang saya daftarkan, lihat hasil edit saya. Gagasan Anda tentang subjektivitas mungkin disebabkan karena OCP hanya memiliki nama yang menyesatkan dan sangat buruk dijelaskan dalam banyak buku teks.
Doc Brown,
Gagasan saya tentang subjektivitas disebabkan oleh fakta bahwa saya tidak sepenuhnya mengerti apa yang Anda katakan - tetapi saya mengerti sekarang, saya kira. Terima kasih banyak atas komentar dan jawaban Anda yang mendalam.
Vadim Samokhin
4

Seperti yang dikatakan orang lain, idealnya kelas pendapatan pekerja akan memungkinkan parameterisasi konstanta, membuat kelas ini independen dari nilai itu.

Pada akhirnya, aplikasi panggilan juga memungkinkan untuk parameterisasi dalam hal konfigurasi eksternal (misalnya file). Setelah kita memiliki konfigurasi eksternal, kita dapat mengubah tarif pajak - meskipun mempertimbangkan bahwa jika file konfigurasi hanya dibaca sekali pada saat startup, maka aplikasi harus direstart agar persentase pajak yang diperbarui berlaku, sehingga ada sesuatu yang harus tetap dalam pikiran. Kami dapat menyediakan fitur aplikasi untuk membaca ulang konfigurasi ketika diarahkan untuk melakukannya, atau kami mungkin menyediakan mekanisme yang lebih rumit yang memperhatikan ketika file konfigurasi berubah ...

Jangka panjang, Anda mungkin menemukan bahwa masalah pajak membutuhkan lebih dari sekadar persentase - misalnya, bahwa suatu hari undang-undang pajak lebih kompleks dan memerlukan beberapa persentase dan beberapa konstanta (misalnya jumlah di bawah $ 10 ribu dikenakan pajak X%, sedangkan sisanya dikenakan pajak pada Y%).

Ini pada dasarnya menyarankan menggunakan pola strategi, di mana kelas utama yang dimaksud di sini menerima objek strategi untuk menghitung pajak.

Berbagai strategi (dan% 's dan $ konstanta) harus dapat dipilih dari file konfigurasi, dan sekarang, menambahkan strategi baru memerlukan penambahan beberapa kode baru, tetapi belum tentu pembaruan untuk kode yang ada.

Setiap strategi mungkin tahu bagaimana mem-parsing / menafsirkan argumen konfigurasi eksternal sendiri, bersama dengan cara menghitung pajak aktual.

Secara dinamis, pajak lebih lanjut tergantung pada pemerintah setempat, jadi Anda mungkin memiliki lokal yang terkait dengan penghasilan atau dengan karyawan (atau keduanya). Dalam konfigurasi eksternal, kami mungkin mengaitkan lokal dengan strategi pajak.


Lihat juga injeksi ketergantungan , tempat kami mengelola hal-hal ini dengan jelas.

Erik Eidt
sumber
1
Pertanyaannya bukan apakah itu ide yang buruk untuk mengubur sesuatu seperti persentase pajak dalam kode, saya yakin itu jelas bagi sebagian besar dari kita di sini (termasuk OP). Pertanyaannya adalah, "Apakah ini melanggar OCP?" Jadi saya tidak melihat bagaimana jawaban Anda mengacu pada pertanyaan ini.
Doc Brown
1

Jika Anda perlu memodifikasi kelas untuk mengubah nilai pajak, maka desainnya memang melanggar OCP. Desain yang sesuai, untuk apa yang telah Anda jelaskan sejauh ini, adalah untuk kelas kalkulator untuk mengambil nilai pajak sebagai parameter.

Jika kelas Anda dipasang (artinya ini bukan kelas statis), dengan membuat properti kelas variabel pajak, yang nilainya disuntikkan melalui konstruktor, Anda juga akan meningkatkan kohesi kelas.

Singkatnya, desain Anda saat ini membuat kelas Anda bergantung pada nilai konstan yang tidak benar-benar konstan (mendefinisikan konstanta sebagai nilai yang tidak akan pernah berubah apa pun yang terjadi, seperti nilai PI). Itu melanggar OCP. Ubah desain untuk menerima nilai pajak sebagai argumen konstruktor.

Christopher Francisco
sumber
0

Sepenuhnya setuju dengan @Becuzz, dan saya hanya ingin meringkas ini: OCP adalah tentang menemukan abstraksi yang digunakan kembali (karenanya, berguna) yang disuntikkan dalam kelas. Jadi perilaku kelas dimodifikasi bukan dengan mengubah kodenya, tetapi dengan menyediakannya dengan implementasi yang berbeda. Ini diperjelas dalam buku Robert Martin " Pengembangan Perangkat Lunak Agile, Prinsip, Pola, dan Praktik ", periksa bab yang sesuai "Prinsip terbuka-terbuka", "Abstraksi adalah Kunci" sub-bab. Ini mengklarifikasi kesalahpahaman lain bahwa perilaku hanya dapat dimodifikasi dengan pewarisan. Bertrand Meyer yang mengusulkan itu pada tahun 1988 dalam bukunya " Object Oriented Software Construction ", bukan Robert Martin.

Vadim Samokhin
sumber
-2

Cara saya melihatnya bukanlah pelanggaran terhadap prinsip tertutup yang terbuka. Namun, fakta bahwa sesuatu yang pasti berubah dalam waktu (seperti persentase pajak) adalah konstan adalah cacat desain: Anda tidak boleh mengubah nilai konstanta tetapi bagaimana Anda menangani persentase pajak. Ini harus menjadi beberapa jenis pengaturan yang dapat dimodifikasi tanpa mengkompilasi ulang semuanya.

Zalomon
sumber
"Cacat desain" adalah bahwa itu melanggar prinsip tertutup terbuka karena Anda perlu mengkompilasi ulang kode untuk mengubah konstanta?
Erdrik Ironrose