Chúng giảm khả năng sử dụng lại theo cách tương tự mà biến toàn cầu thực hiện: khi tính toán của phương pháp phụ thuộc vào trạng thái bên ngoài phương thức, nhưng không được chuyển thành tham số (ví dụ: trường lớp), phương pháp của bạn ít sử dụng được hơn, bởi vì nó được kết hợp chặt chẽ với trạng thái của đối tượng/lớp mà nó cư trú (hoặc tệ hơn, trên một lớp khác hoàn toàn).
Chỉnh sửa: Ok, đây là ví dụ để làm rõ hơn. Tôi đã sử dụng ThreadLocal
chỉ vì lợi ích của câu hỏi, nhưng nó áp dụng cho các biến toàn cầu nói chung. Giả sử tôi muốn tính tổng của N số nguyên đầu tiên song song trên một số luồng. Chúng tôi biết rằng cách tốt nhất để làm điều đó là tính toán số tiền địa phương cho mỗi luồng và tổng hợp chúng ở cuối. Đối với một số lý do chúng tôi quyết định rằng phương pháp call
của mỗi Task
sẽ sử dụng một biến ThreadLocal sum
được định nghĩa trong một lớp học khác nhau như một toàn cầu (tĩnh) biến:
class Foo {
public static ThreadLocal<Long> localSum = new ThreadLocal<Long>() {
public Long initialValue() {
return new Long(0);
}
};
}
class Task implements Callable<Long> {
private int start = 0;
private int end = 0;
public Task(int start, int end) {
this.start = start;
this.end = end;
}
public Long call() {
for(int i = start; i < end; i++) {
Foo.localSum.set(Foo.localSum.get() + i);
}
return Foo.localSum.get();
}
}
Mã này hoạt động một cách chính xác và cung cấp cho chúng ta những giá trị kỳ vọng của tổng số toàn cầu, nhưng chúng tôi nhận thấy rằng lớp Task
và phương pháp call
của chúng tôi hiện được ghép nối hoàn toàn với lớp Foo
. Nếu tôi muốn sử dụng lại lớp Task
trong một dự án khác, tôi cũng phải di chuyển lớp Foo
nếu không mã sẽ không biên dịch.
Mặc dù đây là một ví dụ đơn giản phức tạp về mục đích, bạn có thể thấy các nguy cơ của các biến toàn cầu "ẩn". Nó cũng ảnh hưởng đến khả năng đọc, vì ai đó đọc mã sẽ phải tìm kiếm lớp Foo
và xem định nghĩa của Foo.localSum
là gì. Bạn nên giữ cho các lớp học của bạn càng khép kín càng tốt.
Tôi đã chỉnh sửa câu trả lời của mình bằng một ví dụ mã đơn giản. – Tudor