ความคิดเห็นของคุณบอกว่า "verbose" หมายถึงความจำเป็นในการทำซ้ำบรรทัดของรหัสนี้ในทุกชั้น คำตอบแรกของฉันคือในภาพรวมการเพิ่มโค้ดสองบรรทัด (คำจำกัดความแปรปรวนพร้อมคำสั่งนำเข้า) ในทุกชั้นเรียนนั้นไม่ได้เป็นเรื่องใหญ่ โดยเฉพาะอย่างยิ่งเมื่อคุณต้องการเพิ่มลงในคลาสที่มีพฤติกรรมดังนั้นจึงต้องทำการบันทึก ที่กล่าวว่ารหัสบรรทัดที่คุณใช้นั้นมีแนวโน้มที่จะเกิดข้อผิดพลาดในการคัดลอกวาง (เพิ่มเติมในภายหลัง)
แต่เนื่องจากคุณต้องการทางเลือกนี่คือเหตุผลบางประการที่คุณอาจต้องการหรือไม่ต้องการใช้
ใช้ตัวบันทึกคนเดียวสำหรับทั้งแอพ
หากคุณไม่สนใจว่าคลาสใดที่กำลังรายงานหรือเต็มใจที่จะใส่บริบทที่จำเป็นทั้งหมดไว้ในข้อความกว่าคนตัดไม้ซิงเกิลธรรมดาจะทำงาน:
LoggerSingleton.getInstance().debug("MyController is running")
ในความคิดของฉันประโยชน์ที่สำคัญอย่างหนึ่งของกรอบการบันทึกคือการให้บริบทโดยอินสแตนซ์ของคนตัดไม้แยกต่างหาก - ถ้าเพียงเพื่อส่งข้อความบันทึกไปยังปลายทางที่แตกต่างกัน ฉันจะไม่ยอมแพ้เพียงเพื่อบันทึกโค้ดหนึ่งบรรทัด (คุณยังต้องนำเข้า)
นอกจากนี้ยังเพิ่มการใช้คำฟุ่มเฟื่อยในจุดที่ใช้ซึ่งจะจบลงด้วยการกดแป้นมากขึ้น
สร้างตัวบันทึกของคุณ ณ จุดใช้งาน
ฉันจะโยนอันนี้ออกเพียงเพราะมันกำจัดตัวแปร ฉันไม่คิดว่าฉันต้องการแสดงความคิดเห็น แม้ว่ามันจะแสดงเทคนิคที่ฉันต้องการสำหรับรับอินสแตนซ์คนตัดไม้
Logger.getLogger(getClass()).debug("blah blah blah");
ใช้ bean post-processor เพื่อฉีด logger
ตัวอย่างของคุณใช้ Spring และ Spring ให้คุณเชื่อมต่อกับรหัสการเริ่มต้นถั่ว คุณสามารถสร้างโพสต์โปรเซสเซอร์ที่ตรวจสอบ bean สำหรับlogger
ตัวแปรสมาชิกและสร้างLogger
อินสแตนซ์เมื่อพบหนึ่ง
ในขณะที่โพสต์โปรเซสเซอร์นั้นมีโค้ดเพียงไม่กี่โหล แต่เป็นอีกส่วนหนึ่งที่มีการเคลื่อนไหวในแอปพลิเคชันของคุณ ฉันชอบที่จะมีไม่กี่คนที่เป็นไปได้
ใช้มิกซ์อิน
Scala และ Groovy ให้คุณสมบัติซึ่งช่วยให้คุณสามารถห่อหุ้มพฤติกรรม รูปแบบสกาล่าทั่วไปคือการสร้างLogging
ลักษณะแล้วเพิ่มลงในคลาสที่ต้องมีการบันทึก:
class MyController with Logging
น่าเสียดายนั่นหมายความว่าคุณต้องเปลี่ยนภาษา นอกจากว่าคุณใช้ Java 8 อยู่ในกรณีนี้คุณสามารถสร้างLogging
ส่วนต่อประสานด้วย "default method":
public interface Logging {
default Logger getLogger() {
return Logger.getLogger(getClass());
}
}
ตอนนี้ในรหัสชั้นเรียนของคุณคุณสามารถใช้
getLogger().debug("blah blah blah");
ในขณะที่ง่ายสิ่งนี้มีข้อเสียสองประการ สำหรับสิ่งหนึ่งมันเป็นมลภาวะอินเตอร์เฟสของทุกคลาสที่ใช้เพราะวิธีการอินเตอร์เฟสทั้งหมดเป็นแบบสาธารณะ อาจไม่เลวถ้าคุณใช้เฉพาะคลาสที่อินสแตนซ์และฉีดโดย Spring โดยเฉพาะถ้าคุณทำตามการแยกอินเทอร์เฟซ / การใช้งาน
ปัญหาที่ใหญ่กว่าคือการค้นหาอินสแตนซ์ตัวบันทึกจริงในการโทรทุกครั้ง ซึ่งเร็ว แต่ไม่จำเป็น
และคุณยังต้องการใบแจ้งยอดการนำเข้า
ย้ายตัวบันทึกไปที่ซูเปอร์คลาส
ฉันจะทำซ้ำ: ฉันไม่พบคำจำกัดความตัวทำซ้ำที่ชัดเจน แต่ถ้าคุณทำฉันคิดว่านี่เป็นวิธีที่ดีที่สุดในการกำจัดพวกเขา
public abstract class AbstractController {
protected Logger logger = Logger.getLogger(getClass());
}
ตอนนี้คลาสคอนโทรลเลอร์ของคุณสืบทอดมาAbstractController
แล้วและพวกเขาก็สามารถเข้าถึงlogger
ตัวแปรได้ จำไว้ว่าคุณต้องใส่@Controller
คำอธิบายประกอบลงในคลาสที่เป็นรูปธรรม
บางคนจะพบว่าสิ่งนี้เป็นการบิดเบือนมรดก ผมได้พยายามที่จะระงับโทสะพวกเขาโดยการตั้งชื่อชั้นเรียนมากกว่าAbstractController
AbstractProjectClass
คุณสามารถตัดสินใจด้วยตัวเองหรือไม่ว่ามีความเป็นแบบความสัมพันธ์
คนอื่นจะคัดค้านการใช้ตัวแปรอินสแตนซ์แทนที่จะเป็นตัวแปรสแตติก ตัวบันทึกแบบคงที่IMOมีแนวโน้มที่จะเกิดข้อผิดพลาดในการคัดลอกวางเนื่องจากคุณต้องอ้างอิงชื่อคลาสอย่างชัดเจน getClass()
ตรวจสอบให้แน่ใจว่าคนตัดไม้ของคุณถูกต้องเสมอ
getLogger()
ชื่อของ logger ให้ได้