Giới Thiệu Về Optional trong Java
Chào các bạn! Nếu bạn đã từng lập trình với Java, chắc hẳn bạn không còn xa lạ với lớp Optional. Đây là một Utility class rất hữu ích trong việc kiểm tra null, đặc biệt là khi sử dụng với JPARepository trong các ứng dụng Spring. Trước đây, mình cũng ít khi sử dụng Optional, hầu như chỉ để trả kết quả từ DAO lên Service. Nhưng gần đây, sau khi gặp phải quá nhiều lỗi NullPointerException, mình nhận ra rằng Optional có những tiềm năng thú vị khi kết hợp với định nghĩa hàm (lambda function) trong Java. Nó có thể biến Java từ một ngôn ngữ lập trình hướng đối tượng thuần túy thành một ngôn ngữ lập trình hàm mạnh mẽ hơn, giúp mã code trở nên ngắn gọn, dễ hiểu và đáng tin cậy hơn.
Optional Giúp Tạo Ra Code Sạch Hơn
Hãy cùng nhìn vào một ví dụ đơn giản: bạn muốn pha một ly smoothie và các bước thực hiện bao gồm:
- Mua hoa quả.
- Gọt hoa quả.
- Chuẩn bị đá.
- Bật máy xay và thưởng thức.
Với cách tiếp cận thông thường, đoạn mã có thể trông như sau:
java
public Smoothies makingSmoothies() {
Fruit boughtFruit = buyFruit();
SliceFruit slicedFruit = slicingFruit(boughtFruit);
Ice iceForSmoothies = getIce();
return blendWithIce(slicedFruit, iceForSmoothies);
}
Đúng là đơn giản nhưng trong thực tế, việc này có thể dẫn đến lỗi NullPointerException. Bạn sẽ phải thực hiện kiểm tra null sau mỗi bước như sau:
java
public Smoothies makingSmoothiesWithNullCheck() {
Fruit boughtFruit = buyFruit();
if (boughtFruit != null) {
SliceFruit slicedFruit = slicingFruit(boughtFruit);
if (slicedFruit != null) {
Ice iceForSmoothies = getIce();
if (iceForSmoothies != null) {
return blendWithIce(slicedFruit, iceForSmoothies);
}
throw new RuntimeException();
}
throw new RuntimeException();
}
throw new RuntimeException();
}
Khó khăn ở đây là việc kiểm tra null có thể khiến mã trở nên phức tạp và khó đọc. Với Optional, mã có thể được tối giản hơn:
java
public Smoothies makingSmoothiesWithOptional() {
Fruit boughtFruit = Optional.ofNullable(buyFruit()).orElseThrow(RuntimeException::new);
SliceFruit slicedFruit = Optional.ofNullable(slicingFruit(boughtFruit)).orElseThrow(RuntimeException::new);
Ice iceForSmoothies = Optional.ofNullable(getIce()).orElseThrow(RuntimeException::new);
return Optional.ofNullable(blendWithIce(slicedFruit, iceForSmoothies)).orElseThrow(RuntimeException::new);
}
Có thể thấy, việc sử dụng Optional làm cho code trở nên sạch sẽ và dễ đọc hơn, đồng thời tập trung vào logic kinh doanh chính mà không phải lo lắng về việc kiểm tra null.
Tạo Ra Dòng Dữ Liệu Đơn Giản Với Optional
Không chỉ dừng lại ở việc kiểm tra null, Optional còn giúp quản lý dòng dữ liệu rõ ràng hơn qua hai phương thức map() và flatMap():
java
public Smoothies makingSmoothiesWithStream() {
return Optional.ofNullable(buyFruit())
.map(this::slicingFruit)
.flatMap(slicedFruit -> Optional.ofNullable(getIce())
.map(ice -> blendWithIce(slicedFruit, ice)))
.orElseThrow(RuntimeException::new);
}
Trong đó, chúng ta phân chia các bước làm smoothie thành từng phần nhỏ hơn và mỗi phần có mối liên hệ chặt chẽ với nhau.
Những Nhược Điểm của Optional
Tuy có nhiều lợi ích, nhưng việc sử dụng Optional cũng có một số hạn chế, đặc biệt là trong việc gỡ lỗi. Khi một lỗi xảy ra trong một hàm lambda, thông tin lỗi thường quá chung chung và không chỉ rõ được vị trí xảy ra.
Một giải pháp là tách các hàm lambda thành các phương thức riêng biệt, giúp dễ dàng trong việc quản lý và gỡ lỗi:
java
private Smoothies fermentSmoothies(Smoothies smoothies) {
smoothies.setFerment(true);
return smoothies;
}
Vấn đề gỡ lỗi cần được xử lý cẩn thận, vì log là một thành phần quan trọng để hiểu ngữ cảnh khi xảy ra lỗi.
Kết Luận
Tóm lại, việc sử dụng Optional một cách hợp lý có thể giúp tạo ra các dòng mã code đáng tin cậy và dễ hiểu. Mình đánh giá cao kỹ thuật lập trình này, và việc kết hợp sức mạnh của lập trình hướng đối tượng cùng lập trình hàm thực sự là một điều tuyệt vời. Mặc dù còn nhiều ý kiến khác nhau về khả năng gỡ lỗi và hiệu suất, nhưng việc áp dụng kỹ thuật này đã giúp mình giảm thiểu bug và đơn giản hóa mã code hiệu quả hơn. Hy vọng rằng bạn sẽ tìm thấy điều gì đó hữu ích từ bài viết này!
Thảo Luận
Mình rất mong nhận được ý kiến đóng góp và thảo luận từ mọi người. Nếu bạn muốn tham gia thảo luận thêm, hãy liên hệ với mình qua Telegram tại đây.
source: viblo