Sử dụng chuỗi rỗng, null hoặc xóa thuộc tính trống trong yêu cầu / phản hồi API


25

Khi chuyển đối tượng thông qua API, như ở định dạng JSON của schemaless, cách lý tưởng để trả về thuộc tính chuỗi không tồn tại là gì? Tôi biết rằng có nhiều cách khác nhau để làm điều này như trong các ví dụ trong các liên kết được liệt kê dưới đây.

Tôi chắc chắn rằng tôi đã sử dụng null trong quá khứ nhưng không có lý do chính đáng để làm điều đó. Có vẻ như thẳng về phía trước để sử dụng null khi làm việc với cơ sở dữ liệu. Nhưng cơ sở dữ liệu có vẻ như là một chi tiết triển khai không liên quan đến bên ở phía bên kia của API. Ví dụ, họ có thể sử dụng kho dữ liệu schemaless chỉ lưu trữ các thuộc tính với các giá trị (không null).

Từ quan điểm mã, hạn chế các hàm chuỗi chỉ hoạt động với một loại, tức là string(không phải null), giúp chúng dễ dàng chứng minh hơn; tránh null cũng là một lý do để có Optionđối tượng. Vì vậy, nếu mã tạo ra yêu cầu / phản hồi không sử dụng null, tôi đoán là mã ở phía bên kia của API sẽ không bị buộc phải sử dụng null.

Tôi thích ý tưởng sử dụng một chuỗi rỗng như một cách dễ dàng để tránh sử dụng null. Một đối số mà tôi nghe thấy khi sử dụng null và đối với chuỗi rỗng là chuỗi rỗng có nghĩa là thuộc tính tồn tại. Mặc dù tôi hiểu sự khác biệt, tôi cũng tự hỏi liệu đó chỉ là chi tiết triển khai và nếu sử dụng chuỗi rỗng hoặc chuỗi rỗng có làm cho bất kỳ sự khác biệt trong cuộc sống thực. Tôi cũng tự hỏi nếu một chuỗi rỗng tương tự như một mảng trống.

Vì vậy, đó là cách tốt nhất để làm điều đó giải quyết những mối quan tâm đó? Có phụ thuộc vào định dạng của đối tượng được chuyển (lược đồ / schemaless) không?


2
Cũng lưu ý rằng Oracle xử lý các chuỗi rỗng và chuỗi rỗng theo cùng một cách. Và đúng là: trên một bảng câu hỏi trên giấy, làm thế nào bạn có thể phân biệt giữa không có câu trả lời nào và một câu trả lời bao gồm một chuỗi trống?
Bernhard Hiller

Nếu bạn sử dụng tính kế thừa, có thể dễ dàng nói if( value === null) { use parent value; } Tuy nhiên, nếu bạn đặt giá trị con, thậm chí thành một chuỗi trống (ví dụ: ghi đè giá trị cha mặc định bằng khoảng trống), thì làm thế nào để bạn "thừa kế" giá trị? Đối với tôi, đặt nó là null có nghĩa là "bỏ đặt giá trị này để chúng tôi biết sử dụng giá trị cha."
Frank Forte

Vì "Xóa thuộc tính trống" cũng là lý do để "tránh" a null(đúng nulllà tránh như vậy), nên người hỏi có nghĩa là "Trả về không null" [Đối tượng] (ví dụ: Chuỗi rỗng, Mảng trống, v.v.) khi họ viết "tránh".
cellepo

Câu trả lời:


18

TLDR; Xóa thuộc tính null

Điều đầu tiên cần ghi nhớ là các ứng dụng ở các cạnh của chúng không hướng đối tượng (cũng không có chức năng nếu lập trình theo mô hình đó). JSON mà bạn nhận được không phải là một đối tượng và không nên được xử lý như vậy. Đó chỉ là dữ liệu có cấu trúc có thể (hoặc không) chuyển đổi thành đối tượng. Nói chung, không có JSON nào được tin cậy như một đối tượng kinh doanh cho đến khi nó được xác thực như vậy. Thực tế là nó đã khử lưu huỳnh không làm cho nó hợp lệ. Do JSON cũng có các nguyên hàm hạn chế so với các ngôn ngữ phụ trợ, nên thường tạo ra một DTO được căn chỉnh JSON cho dữ liệu đến. Sau đó, sử dụng DTO để xây dựng một đối tượng kinh doanh (hoặc thử lỗi) để chạy hoạt động API.

Khi bạn xem JSON chỉ là một định dạng truyền, sẽ có ý nghĩa hơn khi bỏ qua các thuộc tính không được đặt. Nó ít hơn để gửi qua dây. Nếu ngôn ngữ back-end của bạn không sử dụng null theo mặc định, có lẽ bạn có thể định cấu hình trình giải mã của mình để báo lỗi. Ví dụ: thiết lập chung của tôi cho Newtonsoft.Json chỉ dịch các thuộc tính null / thiếu sang / từ optioncác loại F # và sẽ có lỗi. Điều này cung cấp một đại diện tự nhiên trong đó các trường là tùy chọn (những trường có optionloại).

Như mọi khi, khái quát hóa chỉ đưa bạn đến nay. Có thể có trường hợp một thuộc tính mặc định hoặc null phù hợp hơn. Nhưng điều quan trọng không phải là xem cấu trúc dữ liệu ở rìa hệ thống của bạn như là đối tượng kinh doanh. Các đối tượng kinh doanh phải mang các đảm bảo kinh doanh (ví dụ tên ít nhất 3 ký tự) khi được tạo thành công. Nhưng cấu trúc dữ liệu kéo ra khỏi dây không có đảm bảo thực sự.


3
Mặc dù hầu hết các bộ nối tiếp hiện đại đều có các trường tùy chọn, bỏ qua null từ phản hồi không phải lúc nào cũng là một ý tưởng hay, bởi vì nó có thể đưa ra sự phức tạp bổ sung để xử lý các trường nullable. Do đó, nó thực sự phụ thuộc vào từng trường hợp , tùy thuộc vào cách thư viện tuần tự hóa của bạn xử lý nullables và liệu độ phức tạp bổ sung (tiềm năng) của việc xử lý các nullable đó có thực sự đáng để lưu một vài byte cho mỗi yêu cầu hay không. Bạn phải làm việc chăm chỉ để phân tích các trường hợp kinh doanh của bạn.
Chris Cirefice

@ChrisCirefice Vâng, tôi tin rằng đoạn cuối bao gồm điều đó. Có những trường hợp sẽ tốt hơn để sử dụng các chiến lược khác nhau.
Kasey speakman

Tôi đồng ý rằng JSON chỉ được sử dụng làm định dạng truyền, nó không truyền đối tượng qua các dây như CORBA. Tôi cũng đồng ý rằng các thuộc tính có thể được thêm và xóa; các đại diện có thể thay đổi, các điều khiển có thể thay đổi, đặc biệt là trên web.
imel96

15

Cập nhật: Tôi đã chỉnh sửa câu trả lời một chút, vì nó có thể dẫn đến nhầm lẫn.


Đi với một chuỗi trống là không có. Chuỗi rỗng vẫn là một giá trị, nó chỉ là rỗng. Không có giá trị nào được chỉ định bằng cách sử dụng cấu trúc đại diện cho không có gì , null.

Từ quan điểm của nhà phát triển API, chỉ tồn tại hai loại thuộc tính:

  • bắt buộc (những PHẢI này có giá trị của loại cụ thể của chúng và KHÔNG bao giờ để trống),
  • tùy chọn (những cái này CÓ THỂ chứa một giá trị của loại cụ thể của chúng nhưng cũng CÓ THỂ chứa null.

Điều này làm cho khá rõ ràng rằng khi một tài sản là bắt buộc, tức là. yêu cầu, nó không bao giờ có thể được null.

Mặt khác, nếu một thuộc tính tùy chọn của một đối tượng không được đặt và để trống, tôi thích giữ chúng trong phản hồi bằng mọi nullgiá trị. Theo kinh nghiệm của tôi, các máy khách API dễ dàng thực hiện phân tích cú pháp hơn, vì chúng không bắt buộc phải kiểm tra xem một thuộc tính có thực sự tồn tại hay không, bởi vì nó luôn ở đó và chúng có thể chuyển đổi phản hồi thành DTO tùy chỉnh của chúng, xử lý nullcác giá trị là tùy chọn.

Tự động bao gồm / loại bỏ các trường khỏi các lực phản ứng bao gồm các điều kiện bổ sung trên máy khách.


Dù bằng cách nào, dù bạn chọn cách nào, hãy đảm bảo bạn giữ nó nhất quán và được ghi chép đầy đủ. Theo cách đó, việc bạn sử dụng API của mình thực sự không quan trọng, miễn là hành vi có thể dự đoán được.


Có, chuỗi rỗng là một giá trị và tôi sử dụng nullđể tham khảo. Trộn các giá trị với các tham chiếu là một trong những mối quan tâm của tôi. Làm thế nào để bạn phân biệt các trường tùy chọn với nullmột trường chuỗi không tùy chọn có nullgiá trị? Phân tích lại, không kiểm tra sự tồn tại thuộc tính làm cho trình phân tích cú pháp dễ vỡ hơn?
imel96

2
@ imel96 Các trường không tùy chọn KHÔNG BAO GIỜ có thể là null. Nếu một cái gì đó không phải là tùy chọn, nó PHẢI luôn chứa một giá trị (thuộc loại cụ thể của nó).
Andy

3
Điều này. Là một người tiêu dùng API thường xuyên, tôi ghét khi tôi phải xử lý các cấu trúc "động" quay trở lại với tôi, ngay cả khi nó ở dạng trường tùy chọn bị bỏ qua. (cũng đồng ý rằng có một sự khác biệt lớn giữa ZLS và Null). Tôi vui vẻ chấp nhận giá trị null cả ngày. Là một tác giả API, một trong những mục tiêu của tôi là làm cho mức tiêu thụ của khách hàng không đau đớn nhất có thể và điều đó có nghĩa là luôn luôn có cấu trúc dữ liệu dự kiến.
jleach

@DavidPacker vì vậy, nếu tôi hiểu chính xác, bạn sử dụng nullđể chỉ ra giá trị là tùy chọn. Vì vậy, khi bạn xác định một đối tượng có thuộc tính chuỗi không tùy chọn và người tiêu dùng không có thuộc tính này, thì nó phải gửi chuỗi rỗng cho thuộc tính đó. Có đúng không?
imel96

2
@GregoryNisbet Đừng làm vậy, làm ơn. Điều đó không có ý nghĩa.
Andy

3

null Sử dụng là ứng dụng / ngôn ngữ phụ thuộc

Cuối cùng, việc lựa chọn sử dụng hay không nulllàm giá trị ứng dụng hợp lệ phần lớn được quyết định bởi ứng dụng và ngôn ngữ / giao diện / cạnh lập trình của bạn.

Ở cấp độ cơ bản, tôi khuyên bạn nên thử sử dụng các loại riêng biệt nếu có các loại giá trị riêng biệt. nullcó thể là một tùy chọn nếu giao diện của bạn cho phép và chỉ có hai loại tài sản bạn đang cố gắng đại diện. Bỏ qua một thuộc tính có thể là một tùy chọn nếu giao diện hoặc định dạng của bạn cho phép nó. Một loại tổng hợp mới (lớp, đối tượng, loại thông báo) có thể là một tùy chọn khác.

Đối với ví dụ chuỗi của bạn, nếu đây là ngôn ngữ lập trình, tôi sẽ tự hỏi mình một vài câu hỏi.

  1. Tôi có kế hoạch thêm các loại giá trị trong tương lai không? Nếu vậy, Optioncó lẽ sẽ tốt hơn cho thiết kế giao diện của bạn.
  2. Khi nào tôi cần xác thực các cuộc gọi của người tiêu dùng? Tĩnh? Năng động? Trước? Sau? Ở tất cả? Nếu ngôn ngữ lập trình của bạn hỗ trợ nó, hãy sử dụng các lợi ích của việc gõ tĩnh vì nó tránh được số lượng mã bạn phải tạo để xác thực. Optioncó thể lấp đầy trường hợp này tốt nhất nếu chuỗi của bạn không thể rỗng. Tuy nhiên, nulldù sao đi nữa , bạn có thể sẽ phải kiểm tra đầu vào của người dùng để biết giá trị chuỗi, vì vậy tôi có thể hoãn lại câu hỏi đầu tiên: tôi muốn đại diện cho bao nhiêu loại giá trị.
  3. nulldấu hiệu của một lỗi lập trình viên trong ngôn ngữ lập trình của tôi? Thật không may, nullthường là giá trị mặc định cho các con trỏ hoặc tham chiếu chưa được khởi tạo (hoặc không được khởi tạo rõ ràng) trong một số ngôn ngữ. Là nullmột giá trị được chấp nhận như giá trị mặc định? Có an toàn như một giá trị mặc định? Đôi khi nulllà biểu thị của các giá trị được giải quyết. Tôi có nên cung cấp cho người tiêu dùng giao diện của mình một dấu hiệu về các vấn đề khởi tạo hoặc quản lý bộ nhớ tiềm năng này trong chương trình của họ không? Chế độ thất bại của một cuộc gọi như vậy khi đối mặt với những vấn đề như vậy là gì? Là người gọi trong cùng một quy trình hoặc chủ đề như của tôi để các lỗi như vậy có nguy cơ cao đối với ứng dụng của tôi?

Tùy thuộc vào câu trả lời của bạn cho những câu hỏi này, có lẽ bạn sẽ có thể trau dồi xem liệu có nullphù hợp với giao diện của bạn hay không .

ví dụ 1

  1. Ứng dụng của bạn rất quan trọng
  2. Bạn đang sử dụng một số loại khởi tạo heap khi khởi động và nulllà giá trị chuỗi có thể được truyền lại khi không thể phân bổ không gian cho chuỗi.
  3. Có một tiềm năng như một chuỗi đánh vào giao diện của bạn

Trả lời: nullcó lẽ không phù hợp

Đặt vấn đề: nulltrong trường hợp này thực sự được sử dụng để chỉ ra hai loại giá trị khác nhau. Giá trị đầu tiên có thể là giá trị mặc định mà người dùng giao diện của bạn có thể muốn đặt. Thật không may, giá trị thứ hai là một lá cờ để chỉ ra rằng hệ thống của bạn không hoạt động chính xác. Trong những trường hợp như vậy, bạn có thể muốn thất bại một cách an toàn nhất có thể (bất cứ điều gì có nghĩa cho hệ thống của bạn).

Ví dụ 2

  1. Bạn đang sử dụng cấu trúc C có char *thành viên.
  2. Hệ thống của bạn không sử dụng phân bổ heap và bạn đang sử dụng kiểm tra MISRA.
  3. Giao diện của bạn chấp nhận cấu trúc này như một con trỏ và kiểm tra để đảm bảo rằng cấu trúc đó không trỏ đến NULL
  4. Giá trị mặc định và an toàn của char *thành viên cho API của bạn có thể được biểu thị bằng một giá trị duy nhất làNULL
  5. Khi khởi tạo cấu trúc người dùng của bạn, bạn muốn cung cấp cho người dùng khả năng không khởi tạo char *thành viên một cách rõ ràng .

Trả lời: NULLcó thể phù hợp

Đặt vấn đề: Có một chút khả năng cấu trúc của bạn vượt qua NULLkiểm tra nhưng chưa được khởi tạo. Tuy nhiên, API của bạn có thể không thể giải thích được điều này trừ khi bạn có một số loại tổng kiểm tra về giá trị cấu trúc và / hoặc kiểm tra phạm vi địa chỉ của cấu trúc. MISRA-C linters có thể giúp người dùng API của bạn bằng cách gắn cờ sử dụng các cấu trúc trước khi khởi tạo. Tuy nhiên, đối với char *thành viên, nếu con trỏ tới struct trỏ đến cấu trúc được khởi tạo, NULLlà giá trị mặc định của thành viên không xác định trong trình khởi tạo cấu trúc. Do đó, NULLcó thể phục vụ như một giá trị mặc định, an toàn cho char *thành viên struct trong ứng dụng của bạn.

Nếu trên giao diện tuần tự hóa, tôi sẽ tự hỏi mình những câu hỏi sau về việc có nên sử dụng null trên chuỗi hay không.

  1. nulldấu hiệu của một lỗi phía khách hàng tiềm năng? Đối với JSON trong JavaScript, điều này có lẽ nulllà không nhất thiết phải được sử dụng như một dấu hiệu của sự thất bại phân bổ. Trong JavaScript, nó được sử dụng như một dấu hiệu rõ ràng về sự vắng mặt của đối tượng khỏi một tham chiếu được đặt một cách có vấn đề. Tuy nhiên, có những trình phân tích cú pháp và trình tuần tự không phải là javascript để ánh xạ JSON nullthành nullkiểu gốc . Nếu đây là trường hợp, điều này đặt ra cuộc thảo luận về việc nullsử dụng bản địa có phù hợp với ngôn ngữ, trình phân tích cú pháp và trình kết nối cụ thể của bạn hay không .
  2. Sự vắng mặt rõ ràng của một giá trị tài sản có ảnh hưởng nhiều hơn một giá trị tài sản không? Đôi khi a nullthực sự chỉ ra rằng bạn có một loại tin nhắn hoàn toàn mới. Người tiêu dùng của bạn có định dạng tuần tự hóa có thể sạch hơn khi chỉ định một loại thông báo hoàn toàn khác. Điều này đảm bảo rằng xác thực và logic ứng dụng của chúng có thể có sự tách biệt rõ ràng giữa hai sự khác biệt của các thông điệp mà giao diện web của bạn cung cấp.

Tư vấn chung

nullkhông thể là một giá trị trên một cạnh hoặc giao diện không hỗ trợ nó. Nếu bạn đang sử dụng thứ gì đó cực kỳ lỏng lẻo khi nhập các giá trị thuộc tính (ví dụ JSON), hãy thử đẩy một số dạng lược đồ hoặc xác thực trên phần mềm cạnh của người tiêu dùng (ví dụ: Lược đồ JSON ) nếu bạn có thể. Nếu đó là API ngôn ngữ lập trình, hãy xác thực tĩnh đầu vào của người dùng nếu có thể (thông qua nhập) hoặc to nhất có thể trong thời gian chạy (còn gọi là lập trình phòng thủ trên giao diện đối mặt với người tiêu dùng). Quan trọng là, tài liệu hoặc xác định cạnh để không có câu hỏi nào về:

  • Loại giá trị nào mà một tài sản nhất định chấp nhận
  • Phạm vi giá trị nào là hợp lệ cho một thuộc tính nhất định.
  • Làm thế nào một loại tổng hợp nên được cấu trúc. Những thuộc tính nào phải / nên / có thể có trong một loại tổng hợp?
  • Nếu đó là một số loại container, thì container có thể chứa bao nhiêu vật phẩm và các loại giá trị mà container chứa là gì?
  • Thứ tự nào, nếu có, là các thuộc tính hoặc thể hiện của một loại container hoặc tổng hợp được trả về?
  • Những tác dụng phụ nào có trong việc thiết lập các giá trị cụ thể và tác dụng phụ của việc đọc các giá trị đó là gì?

1

Dưới đây là phân tích cá nhân của tôi về những câu hỏi này. Nó không được hỗ trợ bởi bất kỳ cuốn sách, giấy, nghiên cứu hoặc bất cứ điều gì, chỉ là kinh nghiệm cá nhân của tôi.

Chuỗi rỗng như null

Đây là một không đi cho tôi. Không trộn lẫn ngữ nghĩa của chuỗi rỗng với không xác định. Trong nhiều trường hợp, chúng có thể được hoán đổi cho nhau một cách hoàn hảo, nhưng bạn có thể gặp phải trường hợp không xác định và xác định nhưng trống rỗng có nghĩa là một cái gì đó khác nhau.

Một loại ví dụ ngu ngốc: giả sử có một thuộc tính lưu trữ khóa ngoại và thuộc tính đó không được xác định hoặc nullcó nghĩa là không có mối quan hệ nào được xác định, trong khi một chuỗi rỗng ""có thể được hiểu là một quan hệ xác định và ID của hồ sơ nước ngoài là chuỗi trống.

Không được xác định vs null

Đây không phải là một chủ đề đen hoặc trắng. Có những ưu và nhược điểm cho cả hai phương pháp.

Để ủng hộ các nullgiá trị được xác định rõ ràng , có những ưu điểm sau:

  • Các tin nhắn tự mô tả nhiều hơn ở chỗ bạn có thể biết tất cả các phím chỉ bằng cách xem bất kỳ tin nhắn nào
  • Liên quan đến điểm trước, việc mã hóa và phát hiện lỗi trong người tiêu dùng dữ liệu sẽ dễ dàng hơn: việc phát hiện lỗi sẽ dễ dàng hơn nếu bạn lấy sai khóa (có thể sai chính tả, có thể API đã thay đổi, v.v.).

Có lợi cho việc giả sử một khóa không tồn tại bằng với ngữ nghĩa của null:

  • Một số thay đổi dễ dàng hơn để ở. Chẳng hạn, nếu một phiên bản mới của lược đồ thông báo bao gồm một khóa mới, bạn có thể mã hóa người tiêu dùng thông tin để làm việc với khóa tương lai này, ngay cả khi nhà sản xuất thư chưa được cập nhật và chưa cung cấp thông tin này.
  • Tin nhắn có thể ít dài dòng hoặc ngắn hơn

Trong trường hợp API ổn định bằng cách nào đó và bạn hoàn toàn ghi lại nó, tôi nghĩ rằng hoàn toàn ổn khi tuyên bố rằng khóa không tồn tại bằng với ý nghĩa của nó null. Nhưng nếu nó lộn xộn và hỗn loạn hơn (vì nó khá thường xuyên), tôi nghĩ bạn có thể tránh đau đầu nếu bạn xác định rõ ràng mọi giá trị trong mỗi tin nhắn. Tức là nếu nghi ngờ, tôi có xu hướng theo cách tiếp cận dài dòng.

Tất cả những gì đã nói, điều quan trọng nhất: nêu rõ ý định của bạn và nhất quán. Đừng làm một điều ở đây và những điều khác ở đó. Phần mềm dự đoán là phần mềm tốt hơn.


Ví dụ cho việc sử dụng các chuỗi rỗng là ý nghĩa của chi tiết triển khai, nghĩa là giả sử API được sử dụng để hiển thị các hàng cơ sở dữ liệu. Nó sẽ làm cho bất kỳ sự khác biệt nếu không có cơ sở dữ liệu liên quan và hoàn toàn để chuyển đại diện đối tượng?
imel96

Nó không phải là một chi tiết thực hiện. Ví dụ của tôi thực sự nói về các PK có liên quan đến DB, nhưng điều tôi cố gắng giải thích là một chuỗi rỗng không phải là không / không có gì / null. Một ví dụ khác: trong một trò chơi, có một đối tượng nhân vật và nó có thuộc tính "đối tác". Một nullđối tác rõ ràng có nghĩa là không có đối tác nào cả, nhưng ""có thể hiểu là có một đối tác có tên "".
bgusach

Tôi ổn với tham chiếu đối tác null có nghĩa là không có đối tác và tham chiếu cũng không phải là một chuỗi. Nhưng tên đối tác là một chuỗi, ngay cả khi bạn cho phép null làm tên đối tác, bạn sẽ không bắt được null đó và thay thế bằng chuỗi trống vào một lúc nào đó?
imel96

Nếu không có đối tác, tôi sẽ không thay đổi nullchuỗi trống. Có thể kết xuất nó dưới dạng, nhưng không bao giờ trong mô hình dữ liệu.
bgusach

Tôi không có nghĩa là không có đối tác, đối tác sẽ là một đối tượng. Đó là đối tác namemà tôi đang nói đến, bạn có cho phép tên đối tác là null không?
imel96

1

Tôi sẽ cung cấp một chuỗi rỗng trong tình huống có một chuỗi và nó là một chuỗi trống. Tôi sẽ cung cấp null trong một tình huống mà tôi muốn nói rõ ràng "không, dữ liệu này không có ở đó". Và bỏ qua chìa khóa để nói "không có dữ liệu ở đó, đừng bận tâm".

Bạn đánh giá những tình huống này có thể xảy ra. Liệu nó có ý nghĩa cho ứng dụng của bạn có chuỗi rỗng? Bạn có muốn phân biệt giữa việc nói rõ ràng "không có dữ liệu" bằng cách sử dụng null và ngầm bằng cách không có giá trị? Bạn chỉ nên có cả hai khả năng (không có và không có khóa) nếu cả hai cần được phân biệt bởi máy khách.

Bây giờ hãy nhớ rằng đây là tất cả về việc truyền dữ liệu. Những gì người nhận làm với dữ liệu là việc của họ và họ sẽ làm những gì thuận tiện nhất với họ. Người nhận sẽ có thể xử lý bất cứ điều gì bạn ném vào nó (có thể bằng cách từ chối dữ liệu) mà không gặp sự cố.

Nếu không có sự cân nhắc nào khác, thì tôi sẽ truyền tải những gì thuận tiện nhất cho người gửi và ghi lại nó. Tôi hoàn toàn không muốn gửi các giá trị vắng mặt vì điều này có khả năng cải thiện tốc độ mã hóa, truyền và phân tích cú pháp JSON.


Tôi thích quan điểm của bạn trong "nếu khách hàng cần phân biệt".
imel96

0

Mặc dù tôi không thể nói điều gì là tốt nhất nhưng gần như chắc chắn không phải là một chi tiết triển khai đơn giản , nó thay đổi cấu trúc về cách bạn có thể tương tác với biến đó.

Nếu một cái gì đó có thể là null, bạn nên luôn luôn coi nó như thể nó sẽ là null tại một số điểm , vì vậy bạn sẽ luôn luôn có hai quy trình công việc , một cho null, một cho chuỗi hợp lệ. Một quy trình phân chia không nhất thiết là một điều xấu, vì có khá nhiều xử lý lỗi và sử dụng trong trường hợp đặc biệt mà bạn có thể sử dụng, nhưng nó làm xáo trộn mã của bạn.

Nếu bạn luôn tương tác với chuỗi theo cùng một cách thì chức năng sẽ dễ dàng hơn trong đầu bạn .

Vì vậy, như với bất kỳ câu hỏi "điều gì là tốt nhất" tôi để lại với câu trả lời: nó phụ thuộc . Nếu bạn muốn phân chia luồng công việc của mình và nắm bắt rõ ràng hơn khi một cái gì đó không được đặt, hãy sử dụng null. Nếu bạn muốn chương trình tiếp tục làm như vậy, hãy sử dụng một chuỗi rỗng. Điều quan trọng là bạn nhất quán , chọn một lợi nhuận chung và gắn bó với điều đó.

Xem xét bạn đang tạo API, tôi khuyên bạn nên sử dụng chuỗi trống vì người dùng sẽ phải bù đắp ít hơn, vì là người dùng API tôi sẽ không biết mọi lý do API của bạn có thể cho tôi giá trị null trừ khi bạn ' tài liệu rất tốt, mà một số người dùng sẽ không đọc.


Có "quy trình phân chia" là xấu. Hãy nói về phía nhà sản xuất mọi thứ đều sạch sẽ, các phương thức kiểu chuỗi chỉ trả về strings, không bao giờ null. Nếu API sử dụng null, thì tại một số điểm, nhà sản xuất cần tạo điều này nullđể phù hợp với API. Thì người tiêu dùng cũng cần xử lý null. Nhưng tôi nghĩ rằng tôi đã hiểu những gì bạn đang nói, chỉ cần quyết định và xác định API có thẩm quyền, phải không? Điều đó có nghĩa là không có gì sai với bất kỳ ai trong số họ?
imel96

Có, bất cứ điều gì bạn làm trong API sẽ ảnh hưởng đến cách người dùng sẽ phải cấu trúc mã của họ, vì vậy, xem xét thiết kế của bạn theo khía cạnh người dùng API, bạn sẽ có thể xác định cách nào là tốt nhất. Cuối cùng, đó là API của bạn. Chỉ cần kiên định. Chỉ có bạn mới có thể quyết định những ưu và nhược điểm của phương pháp này.
Erdrik Ironrose 15/03/2017

0

Tài liệu!

TL; DR>

Làm như bạn thấy phù hợp - đôi khi bối cảnh mà nó được sử dụng là vấn đề. Ví dụ, Biến liên kết với Oracle SQL: Chuỗi rỗng được hiểu là NULL.

Đơn giản tôi sẽ nói - Hãy chắc chắn rằng bạn ghi lại từng kịch bản được đề cập

  • VÔ GIÁ TRỊ
  • Trống (trống)
  • Thiếu (loại bỏ)

Mã của bạn có thể hoạt động theo nhiều cách khác nhau - ghi lại cách mã của bạn phản ứng với nó:

  • Thất bại (Ngoại lệ, v.v.), thậm chí có thể không xác thực (có thể là ngoại lệ được kiểm tra) so với không thể xử lý tình huống một cách chính xác (NullPulumException).
  • Cung cấp mặc định hợp lý
  • Mã hành xử khác nhau

Sau đó, thêm vào đó - tùy thuộc vào bạn để cư xử nhất quán và có thể áp dụng một số thực tiễn tốt nhất của riêng bạn. Tài liệu mà hành vi nhất quán. Ví dụ:

  • Đối xử với Null và mất tích như nhau
  • Hãy đối xử với một chuỗi rỗng chính xác như vậy. Chỉ trong trường hợp liên kết SQL, nó có thể được coi là trống. Hãy chắc chắn rằng SQL của bạn hoạt động nhất quán và theo cách mong đợi.

Vấn đề là, không giải quyết các mối quan tâm, bất đồng đã xảy ra khá thường xuyên. Hãy xem xét trong môi trường nhóm, quyết định phải là quyết định của nhóm, rất nhiều lần điều đó có nghĩa là sẽ có một cuộc tranh cãi. Khi bạn có nhiều đội, mỗi đội được quyền tự quyết định. Tôi đã thấy các API mà tôi chỉ có thể đoán rằng chúng được triển khai bởi các nhóm khác nhau không đồng ý với nhau. Nếu bất kỳ ai có thể đồng ý với một điều, tài liệu đó là chuyện nhỏ.
imel96

0

tl; dr - nếu bạn sử dụng nó: nhất quán trong ý nghĩa của nó.

Nếu bạn bao gồm null , nó có nghĩa là gì? Có một vũ trụ của những điều nó có nghĩa là gì. Một giá trị chỉ đơn giản là không đủ để biểu thị một giá trị bị thiếu hoặc chưa biết (và đây chỉ là hai trong số vô số khả năng: ví dụ: Mất tích - đã được đo, nhưng chúng tôi chưa biết về nó. nó.)

Trong một ví dụ tôi tình cờ gặp gần đây, một trường có thể trống vì nó không được báo cáo để bảo vệ quyền riêng tư của ai đó, nhưng nó được biết đến từ phía người gửi, không biết ở bên gửi, nhưng biết cho phóng viên ban đầu hoặc cả hai đều không biết. Và tất cả những điều này quan trọng đối với người nhận. Vì vậy, thường một giá trị là không đủ.

Với giả định thế giới mở (đơn giản là bạn không biết về những điều không được nêu), bạn sẽ bỏ qua nó và nó có thể là bất cứ điều gì. Với giả định thế giới khép kín (những điều không được nêu là sai, ví dụ như trong SQL), tốt hơn hết bạn nên làm rõ nullnghĩa là gì và phù hợp với định nghĩa đó như bạn có thể ...

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.