Nhận xét của bạn nói rằng "verbose" đề cập đến sự cần thiết phải lặp lại dòng mã này trong mỗi lớp. Phản hồi đầu tiên của tôi là, trong bức tranh lớn, việc thêm hai dòng mã (định nghĩa biến cộng với câu lệnh nhập) vào mỗi lớp không phải là vấn đề lớn. Đặc biệt là vì bạn chỉ cần thêm chúng vào các lớp có hành vi và do đó cần phải đăng nhập. Điều đó nói rằng, dòng mã cụ thể mà bạn đang sử dụng có xu hướng sao chép-dán lỗi (nhiều hơn về sau).
Nhưng, vì bạn muốn có các lựa chọn thay thế, đây là một vài lý do mà bạn có thể muốn hoặc không muốn sử dụng chúng.
Sử dụng một logger duy nhất cho toàn bộ ứng dụng
Nếu bạn không quan tâm đến những gì lớp đang báo cáo, hoặc sẵn sàng đưa tất cả bối cảnh cần thiết vào tin nhắn, thì một trình ghi nhật ký đơn giản sẽ thực hiện công việc:
LoggerSingleton.getInstance().debug("MyController is running")
Theo tôi, một trong những lợi ích lớn của khung đăng nhập là có bối cảnh được cung cấp bởi các phiên bản logger riêng biệt - nếu chỉ để hướng các thông điệp tường trình đến các đích khác nhau. Tôi sẽ không từ bỏ chỉ để lưu một dòng mã (bạn vẫn cần nhập).
Thêm vào đó, điều này làm tăng tính dài dòng tại điểm sử dụng, điều này sẽ kết thúc bằng nhiều lần nhấn phím hơn.
Tạo logger của bạn tại điểm sử dụng
Tôi ném cái này ra chỉ vì nó loại bỏ biến. Tôi không nghĩ rằng tôi cần bình luận về nó. Mặc dù nó cho thấy kỹ thuật ưa thích của tôi để lấy một cá thể logger.
Logger.getLogger(getClass()).debug("blah blah blah");
Sử dụng một bộ xử lý hậu đậu để tiêm logger
Ví dụ của bạn sử dụng Spring và Spring cho phép bạn nối vào mã khởi tạo bean. Bạn có thể tạo một bộ xử lý hậu kiểm tra bean cho một logger
biến thành viên và tạo một Logger
cá thể khi nó tìm thấy một biến.
Mặc dù bộ xử lý hậu như vậy chỉ có vài chục dòng mã, nhưng đó là một phần chuyển động khác trong ứng dụng của bạn và do đó là một nguồn lỗi tiềm năng khác. Tôi thích có càng ít trong số đó càng tốt.
Sử dụng hỗn hợp
Scala và Groovy cung cấp các đặc điểm , cho phép bạn gói gọn hành vi. Một mẫu Scala điển hình là tạo một Logging
đặc điểm, sau đó thêm nó vào lớp cần ghi nhật ký:
class MyController with Logging
Thật không may, điều này có nghĩa là bạn phải chuyển đổi ngôn ngữ. Trừ khi bạn đang sử dụng Java 8, trong trường hợp đó bạn có thể tạo Logging
giao diện với "phương thức mặc định":
public interface Logging {
default Logger getLogger() {
return Logger.getLogger(getClass());
}
}
Bây giờ, trong mã lớp của bạn, bạn chỉ cần sử dụng
getLogger().debug("blah blah blah");
Trong khi dễ dàng, điều này có một vài nhược điểm. Đối với một điều, nó gây ô nhiễm giao diện của mọi lớp sử dụng nó, bởi vì tất cả các phương thức giao diện là công khai. Có lẽ không tệ nếu bạn chỉ sử dụng nó cho các lớp được khởi tạo và chèn bởi Spring, đặc biệt nếu bạn tuân theo phân tách giao diện / triển khai.
Vấn đề lớn hơn là nó phải tra cứu phiên bản logger thực tế trên mỗi cuộc gọi. Cái nào nhanh, nhưng không cần thiết.
Và bạn vẫn cần một báo cáo nhập khẩu.
Di chuyển logger đến một siêu lớp
Tôi sẽ lặp lại: Tôi không tìm thấy các định nghĩa logger lặp đi lặp lại, nhưng nếu bạn nghĩ rằng đây là cách tiếp cận tốt nhất để loại bỏ chúng.
public abstract class AbstractController {
protected Logger logger = Logger.getLogger(getClass());
}
Bây giờ các lớp trình điều khiển của bạn kế thừa từ AbstractController
và chúng có quyền truy cập vào logger
biến. Hãy nhớ rằng bạn phải đặt @Controller
chú thích vào lớp cụ thể.
Một số người sẽ thấy đây là một sự đồi bại của thừa kế. Tôi đã cố gắng làm dịu chúng bằng cách đặt tên cho lớp AbstractController
chứ không phải AbstractProjectClass
. Bạn có thể tự quyết định xem có hay không một mối quan hệ.
Những người khác sẽ phản đối việc sử dụng một biến thể hiện hơn là một biến tĩnh. Trình ghi nhật ký tĩnh IMO dễ bị lỗi sao chép-dán, vì bạn phải tham chiếu rõ ràng tên lớp; getClass()
đảm bảo rằng logger của bạn luôn luôn chính xác.
getLogger()
tên của logger để lấy.