Những người khác đã giải thích rất tốt vấn đề với các singlet nói chung. Tôi chỉ muốn thêm một lưu ý về trường hợp cụ thể của Logger. Tôi đồng ý với bạn rằng thường không có vấn đề gì khi truy cập Logger (hay chính xác là root log) dưới dạng singleton, thông qua static getInstance()
hoặc getRootLogger()
method. (trừ khi bạn muốn xem những gì được ghi lại bởi lớp bạn đang kiểm tra - nhưng theo kinh nghiệm của tôi, tôi khó có thể nhớ lại những trường hợp như vậy khi điều này là cần thiết. Sau đó, một lần nữa, đối với những người khác, đây có thể là một mối quan tâm cấp bách hơn).
IMO thường không phải là một trình ghi nhật ký singleton, vì nó không chứa bất kỳ trạng thái nào liên quan đến lớp bạn đang kiểm tra. Nghĩa là, trạng thái của bộ ghi (và những thay đổi có thể có của nó) không ảnh hưởng gì đến trạng thái của lớp được kiểm tra. Vì vậy, nó không làm cho bài kiểm tra đơn vị của bạn khó khăn hơn nữa.
Giải pháp thay thế sẽ là đưa trình ghi nhật ký qua hàm tạo, vào (gần như) mọi lớp đơn lẻ trong ứng dụng của bạn. Để có tính nhất quán của các giao diện, nó nên được đưa vào ngay cả khi lớp được đề cập không ghi nhật ký bất kỳ thứ gì hiện tại - giải pháp thay thế sẽ là khi bạn phát hiện ra tại một thời điểm nào đó rằng bây giờ bạn cần ghi lại thứ gì đó từ lớp này, bạn cần một trình ghi nhật ký, do đó bạn cần thêm một tham số phương thức khởi tạo cho DI, phá vỡ tất cả mã máy khách. Tôi không thích cả hai tùy chọn này và tôi cảm thấy rằng việc sử dụng DI để ghi nhật ký sẽ chỉ làm phức tạp cuộc sống của tôi để tuân thủ một quy tắc lý thuyết mà không có bất kỳ lợi ích cụ thể nào.
Vì vậy, điểm mấu chốt của tôi là: một lớp được sử dụng (hầu như) phổ biến, nhưng không chứa trạng thái liên quan đến ứng dụng của bạn, có thể được triển khai một cách an toàn dưới dạng Singleton .