Tôi đã đọc trên nhiều trang web Tùy chọn chỉ nên được sử dụng làm loại trả về và không được sử dụng trong các đối số phương thức. Tôi đang đấu tranh để tìm một lý do hợp lý tại sao. Ví dụ tôi có một đoạn logic có 2 tham số tùy chọn. Do đó, tôi nghĩ sẽ rất hợp lý khi viết chữ ký phương thức của mình như thế này (giải pháp 1):
public int calculateSomething(Optional<String> p1, Optional<BigDecimal> p2 {
// my logic
}
Nhiều trang web chỉ định Tùy chọn không nên được sử dụng làm đối số phương thức. Với ý nghĩ này, tôi có thể sử dụng chữ ký phương thức sau và thêm một nhận xét Javadoc rõ ràng để xác định rằng các đối số có thể là null, hy vọng các nhà bảo trì trong tương lai sẽ đọc Javadoc và do đó luôn thực hiện kiểm tra null trước khi sử dụng các đối số (giải pháp 2) :
public int calculateSomething(String p1, BigDecimal p2) {
// my logic
}
Ngoài ra, tôi có thể thay thế phương thức của mình bằng bốn phương thức công khai để cung cấp giao diện đẹp hơn và làm cho p1 và p2 rõ ràng hơn là tùy chọn (giải pháp 3):
public int calculateSomething() {
calculateSomething(null, null);
}
public int calculateSomething(String p1) {
calculateSomething(p1, null);
}
public int calculateSomething(BigDecimal p2) {
calculateSomething(null, p2);
}
public int calculateSomething(String p1, BigDecimal p2) {
// my logic
}
Bây giờ tôi thử viết mã của lớp để gọi đoạn logic này cho mỗi cách tiếp cận. Trước tiên tôi lấy hai tham số đầu vào từ một đối tượng khác trả về Optional
s và sau đó, tôi gọi calculateSomething
. Do đó, nếu giải pháp 1 được sử dụng, mã gọi sẽ như thế này:
Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result = myObject.calculateSomething(p1, p2);
nếu giải pháp 2 được sử dụng, mã cuộc gọi sẽ như thế này:
Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result = myObject.calculateSomething(p1.orElse(null), p2.orElse(null));
nếu giải pháp 3 được áp dụng, tôi có thể sử dụng mã ở trên hoặc tôi có thể sử dụng mã sau (nhưng đó là mã nhiều hơn đáng kể):
Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result;
if (p1.isPresent()) {
if (p2.isPresent()) {
result = myObject.calculateSomething(p1, p2);
} else {
result = myObject.calculateSomething(p1);
}
} else {
if (p2.isPresent()) {
result = myObject.calculateSomething(p2);
} else {
result = myObject.calculateSomething();
}
}
Vì vậy, câu hỏi của tôi là: Tại sao nó được coi là thực hành xấu khi sử dụng Optional
s làm đối số phương thức (xem giải pháp 1)? Nó có vẻ như là giải pháp dễ đọc nhất đối với tôi và làm cho rõ ràng nhất là các tham số có thể trống / null cho các nhà bảo trì trong tương lai. (Tôi biết rằng các nhà thiết kế Optional
dự định nó chỉ được sử dụng làm kiểu trả về, nhưng tôi không thể tìm thấy bất kỳ lý do logic nào để không sử dụng nó trong kịch bản này).
null
?