0
0
Lập trình
Thaycacac
Thaycacac thaycacac

Khám Phá Supplier<T> trong Java: Tạo Giá Trị Lười Biếng

Đăng vào 2 tháng trước

• 3 phút đọc

Giới Thiệu

Trong bài trước, chúng ta đã làm quen với Consumer, giao diện hàm cho việc thực hiện các hành động.

Hôm nay, chúng ta sẽ tập trung vào Supplier, giao diện đơn giản nhưng mạnh mẽ nhất cho việc tạo giá trị lười biếng.

Nếu Predicate quyết định, Function biến đổi, và Consumer thực hiện, thì Suppliernguồn cung. Nó cung cấp giá trị theo yêu cầu, mà không cần đầu vào.

Supplier Là Gì?

Đây là định nghĩa:

java Copy
@FunctionalInterface
public interface Supplier<T> {
    T get();
}
  • Đầu vào: Không có.
  • Đầu ra: Một đối tượng loại T.
  • Mục đích: Tạo ra hoặc cung cấp giá trị, thường là lười biếng hoặc lặp lại.

Tại Sao Nên Sử Dụng Supplier?

Truyền thống, các giá trị được sinh ra theo cách ngay lập tức:

java Copy
String token = UUID.randomUUID().toString();

Với Supplier, chúng ta có thể trì hoãn thực hiện và đóng gói việc tạo giá trị:

java Copy
Supplier<String> tokenSupplier = () -> UUID.randomUUID().toString();

System.out.println(tokenSupplier.get()); // Một token mới cho mỗi lần gọi

Điều này đặc biệt mạnh mẽ trong các tình huống đánh giá lười biếng, tải cấu hình, kiểm thử và tiêm phụ thuộc.

Ví Dụ Thực Tiễn

1. Giá Trị Ngẫu Nhiên hoặc Độc Nhất

Suppliers bộc lộ sự ngẫu nhiên hoặc tạo ra giá trị độc nhất một cách tự nhiên:

java Copy
Supplier<Integer> randomInt = () -> new Random().nextInt(100);

System.out.println(randomInt.get()); // ví dụ: 42
System.out.println(randomInt.get()); // ví dụ: 17

2. Khởi Tạo Hoãn

Trì hoãn tính toán tốn kém cho đến khi cần:

java Copy
Supplier<List<User>> heavyQuery = () -> database.fetchAllUsers();

// Chưa có gì xảy ra
List<User> users = heavyQuery.get(); // Truy vấn chỉ được thực hiện tại đây

3. Nhà Máy và Tạo Đối Tượng

Suppliers là những nhà máy tinh tế:

java Copy
Supplier<User> newUser = () -> new User(UUID.randomUUID().toString());

User user1 = newUser.get();
User user2 = newUser.get();

4. Tích Hợp với Stream

Suppliers làm việc với Stream.generate để tạo ra các chuỗi vô hạn:

java Copy
Supplier<String> uuidSupplier = () -> UUID.randomUUID().toString();

List<String> ids = Stream.generate(uuidSupplier)
    .limit(3)
    .toList();

System.out.println(ids); 
// [550e8400-e29b-41d4-a716-446655440000, ...]

Mô Hình Thế Giới Thực

  1. Nhà Cung Cấp Cấu Hình:
    Tải cấu hình lười biếng khi được yêu cầu.

  2. Lưu Trữ với Đánh Giá Lười:
    Tính toán một lần, sau đó tái sử dụng.

  3. Tiêm Phụ Thuộc:
    Truyền Suppliers thay vì các đối tượng cụ thể để tạo ra đối tượng linh hoạt.

  4. Kiểm Thử và Giả Mạo:
    Suppliers giúp dễ dàng tiêm dữ liệu giả hoặc dữ liệu mô phỏng.

Thực Hành Tốt Nhất

  • Giữ Cho Suppliers Trong Sạch: Tránh các tác động phụ ẩn. Suppliers nên chủ yếu tạo ra giá trị.
  • Đặt Tên Rõ Ràng: Sử dụng tên như tokenSupplier, userFactory, configProvider.
  • Kết Hợp với Hàm Bậc Cao: Suppliers có thể được truyền vào các phương thức để trì hoãn thực hiện hoặc tùy chỉnh hành vi.

Cạm Bẫy Thường Gặp

  • Luồng Vô Tận Không Kiểm Soát: Stream.generate không có giới hạn dẫn đến vòng lặp vô hạn.
  • Logic Nặng Nề Bên Trong: Đừng giấu các phép toán phức tạp trong Supplier#get(), nó nên nhẹ và dễ dự đoán.
  • Tác Động Phụ: Mặc dù có thể, nhưng các suppliers có tác động phụ (ví dụ: gọi mạng) làm mờ trách nhiệm. Thích sự thuần khiết hơn.

Phân Tích Chức Năng

Hãy nghĩ về Supplier như một cái giếng:

  • Bạn không cung cấp gì cho nó.
  • Mỗi khi bạn rút nước (get()), nó cung cấp cho bạn nước tươi (T).
  • Cái giếng có thể sâu, vô hạn, hoặc được lưu trữ, nhưng nó luôn cung cấp.

Kết Luận

Supplier là trình tạo lười biếng của Java chức năng.
Nó đóng gói việc tạo giá trị, hỗ trợ đánh giá lười, và tích hợp liền mạch với các luồng, nhà máy, và chiến lược kiểm thử.

Bằng cách làm chủ Supplier, bạn mở khóa tính toán theo yêu cầutạo đối tượng linh hoạt.

Tiếp Theo Là Gì

Trong tập tiếp theo, chúng ta sẽ tìm hiểu về UnaryOperator, một hàm chuyên biệt cho việc biến đổi đầu vào đơn.
Trong khi Function biến đổi từ loại này sang loại khác, UnaryOperator chuyên biệt trong việc biến đổi trong cùng một loại, là một yếu tố nền tảng của sự kết hợp chức năng.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào