Tại sao java.time có các phương thức để tạo các đối tượng thay vì chỉ các hàm tạo?


8

Trong gói java.time mới, các lớp lõi đang sử dụng phương thức nhà máy ofthay vì một hàm tạo công khai. Mặc dù tôi thích mỹ phẩm của ofphương pháp này nhưng tôi không thể thấy lý do chính đáng để không sử dụng hàm tạo. Tài liệu tôi tìm thấy chỉ giải thích rằng đây là trường hợp và không thực sự đi vào lý do tại sao nó lại như vậy.

Trích dẫn từ hướng dẫn :

Hầu hết các lớp trong API thời gian tạo các đối tượng là bất biến, có nghĩa là, sau khi đối tượng được tạo, nó không thể được sửa đổi. Để thay đổi giá trị của một đối tượng bất biến, một đối tượng mới phải được xây dựng như một bản sao sửa đổi của bản gốc. Điều này cũng có nghĩa là API Ngày giờ, theo định nghĩa, an toàn cho chuỗi. Điều này ảnh hưởng đến API ở chỗ hầu hết các phương thức được sử dụng để tạo các đối tượng ngày hoặc thời gian đều có tiền tố là từ, từ hoặc với, chứ không phải là hàm tạo và không có phương thức nào được đặt.

Câu trả lời:


9

Phương pháp nhà máy cho phép đơn giản hóa các nhà thầu - sự khác biệt đó ví dụ trong thời gian được biểu diễn bởi các đối tượng có thể được tách ra từ tính ngay lập tức.

Có rất nhiều phương thức xuất xưởng, một số thực hiện phân tích chuỗi, một số chuyển đổi từ một số biểu diễn ngày hoặc thời gian khác, nhưng tất cả những gì có thể xảy ra trước khi Đối tượng phải được tạo (nếu việc tạo Đối tượng mới thậm chí còn cần thiết - cũng có thể là một lưu trữ một cái).

Một lợi thế lớn khác là các phương thức xuất xưởng có thể có các tên mô tả : các phương thức để phân tích cú pháp biểu diễn Chuỗi được đặt tên, ví dụ LocalTime.parse- điều đó là không thể đối với các hàm tạo.


Để cải thiện câu trả lời này, bạn có thể thêm một ví dụ từ đối tượng Tháng ví dụ chọn đối tượng nào sẽ trả về trong phương thức xuất xưởng.
Softarn

8

Không phải lúc nào cũng cần thiết để tạo một đối tượng mới khi có được giá trị của loại không thay đổi. Một phương thức nhà máy có thể trả về một đối tượng đã được tạo trong khi lệnh gọi hàm tạo luôn tạo một đối tượng mới.

Có một số lợi thế khác đối với các phương thức của nhà máy, nhưng chúng không liên quan chặt chẽ đến tính bất biến và API Ngày giờ. Ví dụ, các phương thức nhà máy có tên và chúng có thể trả về các đối tượng của một số kiểu con.


5

Tôi đã không thiết kế hoặc viết API ngày giờ của Java, vì vậy tôi không thể dứt khoát nói "tại sao họ lại làm theo cách này". Tuy nhiên tôi có thể đề xuất hai lý do chính họ nên làm theo cách này:

  1. Sức mạnh biểu cảm
  2. Dạng song song

Trước tiên, hãy xem xét bối cảnh: mã ngày và mã thời gian của Java là một gói lớn, phức tạp xử lý một vấn đề rất phức tạp. Phổ biến như "thời gian" là, việc thực hiện khái niệm này bao gồm hàng tá cách hiểu và định dạng, với các biến thể giữa các vị trí địa lý (múi giờ), ngôn ngữ, hệ thống lịch, độ phân giải đồng hồ, thang đo thời gian, biểu diễn số, nguồn dữ liệu và khoảng thời gian. Deltas khắc phục (ví dụ: năm nhuận / ngày) là phổ biến và có thể được chèn bất thường bất cứ lúc nào (giây nhuận). Tuy nhiên, gói là một tính năng cốt lõi, có khả năng được sử dụng rộng rãi và dự kiến ​​sẽ xử lý tất cả các biến thể đó một cách chính xác và chính xác. Đó là một trật tự cao. Kết quả, không đáng ngạc nhiên, là một API phức tạp bao gồm nhiều lớp, mỗi lớp có nhiều phương thức.

Bây giờ, tại sao sử dụng ofcác phương thức chứ không phải là một hàm tạo lớp "thông thường"? Ví dụ , tại sao LocalDate.of(...), LocalDate.ofEpochDay(...)LocalDate.ofYearDay(...)thay vì chỉ một số ít các new LocalDate(...)cuộc gọi?

Đầu tiên, sức mạnh biểu cảm : Các phương thức được đặt tên riêng lẻ thể hiện ý định xây dựng và hình thức của dữ liệu được tiêu thụ.

Giả sử trong giây lát rằng quá tải phương thức của Java là đủ để cho phép nhiều loại hàm tạo mà bạn muốn. (Không tham gia vào một cuộc thảo luận về tính năng ngôn ngữ xung quanh việc gõ vịtđơn so với động so với nhiều công văn tôi sẽ chỉ nói: đôi khi điều này là đúng, đôi khi không. Hiện tại, chỉ giả sử không có giới hạn kỹ thuật.)

Có thể tài liệu của nhà xây dựng có thể nêu "khi chỉ được thông qua một longgiá trị duy nhất , giá trị đó được hiểu là số ngày kỷ nguyên, không phải là một năm." Nếu các kiểu dữ liệu mức thấp được truyền cho các hàm tạo khác là khác nhau (ví dụ: chỉ sử dụng trường hợp epoch longvà tất cả các hàm tạo khác sử dụng int), bạn có thể thoát khỏi điều này.

Nếu bạn đã xem mã gọi một hàm LocalDatetạo với một hàm duy nhất long, nó sẽ trông rất giống với mã trong đó một năm được truyền vào, đặc biệt là với một năm được cho là trường hợp phổ biến nhất. Có nhà xây dựng chung đó có thể là có thể, nhưng nó sẽ không nhất thiết dẫn đến sự rõ ràng tuyệt vời.

API gọi rõ ràng ofEpochDay, tuy nhiên, báo hiệu một sự khác biệt rõ ràng về đơn vị và ý định. Tương tự như vậy LocalDate.ofYearDaybáo hiệu rằng monththam số chung đang bị bỏ qua và tham số ngày, trong khi vẫn là int, dayOfYearkhông phải là a dayOfMonth. Các phương thức xây dựng rõ ràng được dự định để diễn tả những gì đang diễn ra với sự rõ ràng hơn.

Các ngôn ngữ tự động và gõ vịt như Python và JavaScript có các phương tiện khác để báo hiệu các diễn giải thay thế (ví dụ: các tham số tùy chọn và giá trị sentinel ngoài băng ), nhưng ngay cả các nhà phát triển Python và JS thường sử dụng các tên phương thức phân biệt để báo hiệu các cách hiểu khác nhau. Nó thậm chí còn phổ biến hơn trong Java, với cả các ràng buộc kỹ thuật của nó (đó là ngôn ngữ gửi đơn, được gửi tĩnh) và các quy ước / thành ngữ văn hóa của nó.

Thứ hai, hình thức song song . LocalDatecó thể cung cấp một hàm tạo Java tiêu chuẩn ngoài, hoặc thay cho hai ofphương thức của nó . Nhưng đến cuối cùng thì sao? Nó vẫn cần ofEpochDayofDayYearcho những trường hợp sử dụng. Một số lớp cung cấp cả hàm tạo và tương đương với các ofXYZphương thức - ví dụ, cả hai Float('3.14')Float.parseFloat('3.14')tồn tại. Nhưng nếu bạn cần các nhà ofXYZxây dựng cho một số thứ, tại sao không sử dụng chúng mọi lúc? Điều đó đơn giản hơn, thường xuyên hơn và song song hơn. Là một kiểu bất biến, phần lớn các LocalDatephương thức là các hàm tạo. Có nhóm chính bảy trong số các phương pháp mà xây dựng trường mới (tương ứng, at, from, minus, of, parse,pluswithtiền tố). Trong số LocalDatehơn 60 phương thức, 35+ là các hàm tạo thực tế . Chỉ có 2 trong số đó có thể dễ dàng chuyển đổi thành các hàm tạo dựa trên lớp tiêu chuẩn. Liệu nó thực sự có ý nghĩa với trường hợp đặc biệt 2 người đó theo cách không song song với tất cả những người khác? Mã khách hàng sử dụng hai hàm tạo trường hợp đặc biệt này sẽ rõ ràng hơn hoặc đơn giản hơn? Chắc là không. Nó thậm chí có thể làm cho mã máy khách trở nên đa dạng hơn và ít đơn giản hơn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.