Ketika memikirkan pengembangan perangkat lunak yang gesit dan semua prinsip (SRP, OCP, ...) Saya bertanya pada diri sendiri bagaimana memperlakukan logging.
Apakah logging di sebelah implementasi merupakan pelanggaran SRP?
Saya akan mengatakan yes
karena implementasinya juga harus dapat berjalan tanpa logging. Jadi bagaimana saya bisa menerapkan logging dengan cara yang lebih baik? Saya telah memeriksa beberapa pola dan sampai pada kesimpulan bahwa cara terbaik untuk tidak melanggar prinsip-prinsip dengan cara yang ditentukan pengguna, tetapi menggunakan pola apa pun yang diketahui melanggar prinsip adalah dengan menggunakan pola dekorator.
Katakanlah kita memiliki banyak komponen tanpa pelanggaran SRP dan kemudian kita ingin menambahkan logging.
- komponen A
- komponen B menggunakan A
Kami ingin masuk untuk A, jadi kami membuat komponen lain D dihiasi dengan A keduanya mengimplementasikan antarmuka I.
- antarmuka I
- komponen L (komponen pencatatan sistem)
- komponen A mengimplementasikan I
- komponen D mengimplementasikan I, menghias / menggunakan A, menggunakan L untuk logging
- komponen B menggunakan I
Keuntungan: - Saya dapat menggunakan A tanpa pencatatan - pengujian A berarti saya tidak memerlukan cemoohan pencatatan - pengujian lebih mudah
Kerugian: - lebih banyak komponen dan lebih banyak tes
Saya tahu ini sepertinya pertanyaan diskusi terbuka lain, tetapi saya sebenarnya ingin tahu apakah seseorang menggunakan strategi logging yang lebih baik daripada dekorator atau pelanggaran SRP. Bagaimana dengan statis singleton logger yang merupakan default NullLogger dan jika syslog-logging diinginkan, seseorang mengubah objek implementasi saat runtime?
Jawaban:
Ya itu merupakan pelanggaran terhadap SRP karena penebangan merupakan masalah lintas sektoral.
Cara yang benar adalah dengan mendelegasikan logging ke kelas logger (Intersepsi) yang tujuan utamanya adalah untuk log - patuh oleh SRP.
Lihat tautan ini untuk contoh yang baik: https://msdn.microsoft.com/en-us/library/dn178467%28v=pandp.30%29.aspx
Ini adalah contoh singkat :
Manfaatnya termasuk
sumber
TenantStoreLogger
akan berubah setiap kaliTenantStore
berubah. Anda tidak akan memisahkan kekhawatiran lebih dari pada solusi awal.Saya akan mengatakan Anda mengambil SRP terlalu serius. Jika kode Anda cukup rapi bahwa penebangan adalah satu-satunya "pelanggaran" SRP maka Anda melakukan lebih baik dari 99% dari semua programmer lain, dan Anda harus menepuk punggung Anda sendiri.
Maksud SRP adalah untuk menghindari kode spageti yang mengerikan di mana kode yang melakukan hal-hal yang berbeda semuanya digabungkan menjadi satu. Mencampur logging dengan kode fungsional tidak membunyikan lonceng alarm untuk saya.
sumber
Do you mock the logger?
:, itulah yang Anda lakukan. Anda harus memilikiILogger
antarmuka yang mendefinisikan APA yang dilakukan oleh logger. Kode yang diuji akan disuntikkan dengan kodeILogger
yang Anda tentukan. Untuk pengujian, Anda harusclass TestLogger : ILogger
. Hal yang hebat tentang ini adalahTestLogger
dapat mengekspos hal-hal seperti string terakhir atau kesalahan yang dicatat. Tes dapat memverifikasi bahwa kode yang diuji masuk dengan benar. Sebagai contoh, sebuah tes bisa jadiUserSignInTimeGetsLogged()
, di mana tes memeriksaTestLogger
log.Tidak, ini bukan pelanggaran SRP.
Pesan yang Anda kirim ke log harus berubah karena alasan yang sama dengan kode di sekitarnya.
Apa yang merupakan pelanggaran terhadap SRP menggunakan perpustakaan khusus untuk masuk langsung ke dalam kode. Jika Anda memutuskan untuk mengubah cara logging, SRP menyatakan bahwa itu tidak akan berdampak pada kode bisnis Anda.
Beberapa jenis abstrak
Logger
harus dapat diakses oleh kode implementasi Anda, dan satu-satunya hal implementasi Anda harus katakan adalah "Kirim pesan ini ke log", tanpa khawatir bagaimana cara melakukannya. Memutuskan cara penebangan yang tepat (bahkan cap waktu) bukanlah tanggung jawab implementasi Anda.Implementasi Anda juga seharusnya tidak tahu apakah logger itu mengirim pesan ke adalah
NullLogger
.Itu kata.
Saya tidak akan menyapu logging sebagai masalah lintas sektoral terlalu cepat . Memancarkan log untuk melacak peristiwa spesifik yang terjadi dalam kode implementasi Anda milik kode implementasi.
Apa yang menjadi perhatian lintas sektoral, OTOH, adalah penelusuran eksekusi : penebangan masuk dan keluar di setiap metode. AOP paling baik ditempatkan untuk melakukan ini.
sumber
Login
-muka dihiasi dengan logger yang sama.Karena penebangan sering dianggap sebagai masalah lintas sektoral, saya sarankan menggunakan AOP untuk memisahkan penebangan dari implementasi.
Bergantung pada bahasa yang Anda gunakan pencegat atau kerangka kerja AOP (misalnya AspectJ di Jawa) untuk melakukan ini.
Pertanyaannya adalah apakah ini benar-benar layak untuk direpotkan. Perhatikan bahwa pemisahan ini akan menambah kerumitan proyek Anda sambil memberikan sedikit manfaat.
sumber
Ini kedengarannya bagus. Anda menggambarkan dekorator logging yang cukup standar. Kamu punya:
Ini memiliki satu tanggung jawab: mencatat informasi yang diberikan padanya.
Ini memiliki satu tanggung jawab: menyediakan implementasi antarmuka I (dengan asumsi saya sesuai dengan SRP, yaitu).
Ini adalah bagian penting:
Ketika dinyatakan seperti itu, kedengarannya rumit, tetapi lihat seperti ini: Komponen D melakukan satu hal: menyatukan A dan L.
Satu- satunya tanggung jawab yang dimiliki komponen D adalah memastikan bahwa L diberitahu ketika A digunakan. Implementasi A dan L keduanya di tempat lain. Ini sepenuhnya sesuai dengan SRP, serta menjadi contoh rapi dari OCP dan penggunaan dekorator yang lumrah.
Peringatan penting: ketika D menggunakan komponen logging Anda L, itu harus melakukannya dengan cara yang memungkinkan Anda mengubah cara Anda login. Cara paling sederhana untuk melakukan ini adalah memiliki antarmuka IL yang diterapkan oleh L. Lalu:
Dengan begitu, tidak ada yang bergantung secara langsung pada hal lain, sehingga mudah untuk menukar mereka. Ini membuatnya mudah untuk beradaptasi dengan perubahan, dan mudah untuk mengejek bagian dari sistem sehingga Anda dapat menguji unit.
sumber
D implements I
. Terima kasih atas jawaban Anda.Tentu saja itu merupakan pelanggaran SRP karena Anda memiliki masalah lintas sektoral. Namun Anda dapat membuat kelas yang bertanggung jawab untuk menyusun logging dengan mengeksekusi tindakan apa pun.
contoh:
sumber