Sai lầm chính của bạn là bạn vẫn đang suy nghĩ theo các thuật ngữ thủ tục hơn. Điều này không có nghĩa là một lời chỉ trích bạn như một người, nó chỉ là một quan sát. Suy nghĩ theo các thuật ngữ chức năng hơn đi kèm với thời gian và thực hành, và do đó các phương pháp là Hiện diện và có được vẻ như là những điều chính xác rõ ràng nhất để gọi cho bạn. Lỗi nhỏ thứ cấp của bạn là tạo Tùy chọn bên trong phương thức của bạn. Tùy chọn có nghĩa là để giúp tài liệu rằng một cái gì đó có thể hoặc không thể trả về một giá trị. Bạn có thể không nhận được gì.
Điều này đã dẫn đến việc bạn viết mã hoàn toàn dễ đọc có vẻ hoàn toàn hợp lý, nhưng bạn đã bị quyến rũ bởi những cám dỗ song sinh tệ hại có được và có mặt.
Tất nhiên câu hỏi nhanh chóng trở thành "tại sao isPftime và thậm chí đến đó?"
Một điều mà nhiều người ở đây bỏ lỡ đó là isPftime () là nó không phải là thứ được tạo ra cho mã mới được viết bởi những người hoàn toàn trên tàu với cách thức lambdas hữu ích, và những người thích chức năng này.
Tuy nhiên, nó mang lại cho chúng ta một vài (hai) lợi ích tốt, tuyệt vời, quyến rũ (?):
- Nó giúp giảm bớt sự chuyển đổi của mã kế thừa để sử dụng các tính năng mới.
- Nó làm giảm các đường cong học tập của Tùy chọn.
Cái đầu tiên khá đơn giản.
Hãy tưởng tượng bạn có một API trông như thế này:
public interface SnickersCounter {
/**
* Provides a proper count of how many snickers have been consumed in total.
*/
public SnickersCount howManySnickersHaveBeenEaten();
/**
* returns the last snickers eaten.<br>
* If no snickers have been eaten null is returned for contrived reasons.
*/
public Snickers lastConsumedSnickers();
}
Và bạn đã có một lớp kế thừa bằng cách sử dụng này (điền vào chỗ trống):
Snickers lastSnickers = snickersCounter.lastConsumedSnickers();
if(null == lastSnickers) {
throw new NoSuchSnickersException();
}
else {
consumer.giveDiabetes(lastSnickers);
}
Một ví dụ giả định để chắc chắn. Nhưng hãy chịu đựng tôi ở đây.
Java 8 hiện đã được khởi chạy và chúng tôi đang tranh giành để có được. Vì vậy, một trong những điều chúng tôi làm là chúng tôi muốn thay thế giao diện cũ của mình bằng một cái gì đó trả về Tùy chọn. Tại sao? Bởi vì như một người khác đã đề cập một cách ân cần:
Điều này đưa ra phỏng đoán về việc liệu thứ gì đó có thể là null hay không.
Điều này đã được những người khác chỉ ra. Nhưng bây giờ chúng tôi có một vấn đề. Hãy tưởng tượng chúng ta có (xin lỗi trong khi tôi nhấn alt + F7 bằng một phương thức vô tội), 46 vị trí mà phương thức này được gọi là mã kế thừa được kiểm tra tốt, thực hiện một công việc tuyệt vời khác. Bây giờ bạn phải cập nhật tất cả những điều này.
ĐÂY là nơi tỏa sáng.
Bởi vì bây giờ: Snickers lastSnickers = snickersC gặp.lastConsumedSnickers (); if (null == lastSnickers) {ném NoSuchSnickersException () mới; } other {Consumer.giveDzheim (LastSnickers); }
trở thành:
Optional<Snickers> lastSnickers = snickersCounter.lastConsumedSnickers();
if(!lastSnickers.isPresent()) {
throw new NoSuchSnickersException();
}
else {
consumer.giveDiabetes(lastSnickers.get());
}
Và đây là một thay đổi đơn giản mà bạn có thể cung cấp cho đàn em mới: Anh ấy có thể làm điều gì đó hữu ích, và anh ấy sẽ được khám phá cơ sở mã hóa cùng một lúc. đôi bên cùng có lợi Rốt cuộc, một cái gì đó giống với mô hình này là khá phổ biến. Và bây giờ bạn không phải viết lại mã để sử dụng lambdas hay bất cứ thứ gì. (Trong trường hợp cụ thể này sẽ là chuyện nhỏ, nhưng tôi để lại những ví dụ về việc nó sẽ khó khăn như một bài tập cho người đọc.)
Lưu ý rằng điều này có nghĩa là cách bạn đã làm về cơ bản là một cách để xử lý mã kế thừa mà không phải viết lại tốn kém. Vậy còn mã mới thì sao?
Chà, trong trường hợp của bạn, nơi bạn chỉ muốn in ra một cái gì đó, bạn chỉ cần làm:
snickersC gặp.lastConsumedSnickers (). ifPftime (System.out :: println);
Đó là khá đơn giản, và hoàn toàn rõ ràng. Điểm mà từ từ nổi lên trên bề mặt sau đó, là có các trường hợp sử dụng cho get () và isPftime (). Họ ở đó để cho phép bạn sửa đổi mã hiện có một cách máy móc để sử dụng các loại mới hơn mà không phải suy nghĩ quá nhiều về nó. Do đó, những gì bạn đang làm là sai lầm theo những cách sau:
- Bạn đang gọi một phương thức có thể trả về null. Ý tưởng đúng sẽ là phương thức trả về null.
- Bạn đang sử dụng các phương thức băng bó kế thừa để đối phó với tùy chọn này, thay vì sử dụng các phương thức mới ngon miệng có chứa lambda fanciness.
Nếu bạn muốn sử dụng Tùy chọn dưới dạng kiểm tra an toàn null đơn giản, điều bạn nên làm chỉ đơn giản là:
new Optional.ofNullable(employeeServive.getEmployee())
.map(Employee::getId)
.ifPresent(System.out::println);
Tất nhiên, phiên bản ưa nhìn của nó trông giống như:
employeeService.getEmployee()
.map(Employee::getId)
.ifPresent(System.out::println);
Nhân tiện, mặc dù không có nghĩa là bắt buộc, tôi khuyên bạn nên sử dụng một dòng mới cho mỗi thao tác để dễ đọc hơn. Dễ đọc và hiểu nhịp đập bất kỳ ngày nào trong tuần.
Tất nhiên đây là một ví dụ rất đơn giản, nơi dễ hiểu mọi thứ chúng tôi đang cố gắng thực hiện. Nó không phải lúc nào cũng đơn giản trong cuộc sống thực. Nhưng hãy chú ý làm thế nào trong ví dụ này, những gì chúng tôi thể hiện là ý định của chúng tôi. Chúng tôi muốn NHẬN nhân viên, NHẬN ID của anh ấy và nếu có thể, hãy in nó. Đây là chiến thắng lớn thứ hai với Tùy chọn. Nó cho phép chúng ta tạo mã rõ ràng hơn. Tôi cũng nghĩ rằng làm những việc như tạo ra một phương pháp thực hiện một loạt các công cụ để bạn có thể đưa nó vào bản đồ nói chung là một ý tưởng tốt.