ใช้สตริงว่างเป็นโมฆะหรือลบคุณสมบัติว่างในคำขอ API / ตอบกลับ


25

เมื่อถ่ายโอนออบเจ็กต์ผ่าน API เช่นเดียวกับในรูปแบบ schemaless JSON วิธีที่เหมาะสมที่สุดในการส่งคืนคุณสมบัติสตริงที่ไม่มีอยู่คืออะไร? ฉันรู้ว่ามีหลายวิธีในการทำเช่นนี้ในตัวอย่างในลิงค์ด้านล่าง

ฉันแน่ใจว่าฉันเคยใช้เป็นโมฆะในอดีต แต่ไม่มีเหตุผลที่ดีที่จะทำเช่นนั้น ดูเหมือนว่าจะใช้ null ทันทีเมื่อจัดการกับฐานข้อมูล แต่ฐานข้อมูลดูเหมือนว่ารายละเอียดการใช้งานที่ไม่ควรเกี่ยวข้องกับฝ่ายที่อยู่อีกด้านหนึ่งของ API เช่นพวกเขาอาจใช้ที่เก็บข้อมูลสกีมาที่เก็บเฉพาะคุณสมบัติที่มีค่า (ไม่ใช่ค่า Null)

จากมุมมองของรหัสการ จำกัด ฟังก์ชั่นสตริงให้ใช้งานได้กับประเภทเดียวเท่านั้นคือstring(ไม่ใช่ null) ทำให้ง่ายต่อการพิสูจน์ หลีกเลี่ยงโมฆะก็เป็นสาเหตุของการมีOptionวัตถุ ดังนั้นหากรหัสที่สร้างคำขอ / ตอบสนองไม่ได้ใช้ค่า null ฉันเดาว่าเป็นรหัสที่อีกด้านหนึ่งของ API จะไม่ถูกบังคับให้ใช้ค่า null เช่นกัน

ฉันชอบความคิดที่จะใช้สตริงว่างเปล่าเป็นวิธีง่ายๆในการหลีกเลี่ยงการใช้ null อาร์กิวเมนต์หนึ่งที่ฉันได้ยินว่าใช้ null และเทียบกับสตริงว่างคือสตริงว่างหมายความว่ามีคุณสมบัติอยู่ แม้ว่าฉันจะเข้าใจความแตกต่างฉันยังสงสัยว่ามันเป็นเพียงรายละเอียดการใช้งานและถ้าใช้สตริงว่างหรือว่างเปล่าทำให้เกิดความแตกต่างในชีวิตจริง ฉันยังสงสัยว่าสตริงว่างนั้นคล้ายคลึงกับอาร์เรย์ว่างหรือไม่

ดังนั้นวิธีไหนที่ดีที่สุดในการทำสิ่งเหล่านี้ มันขึ้นอยู่กับรูปแบบของวัตถุที่ถูกถ่ายโอน (schema / schemaless) หรือไม่?


2
นอกจากนี้โปรดทราบว่า Oracle ใช้สตริงว่างและสตริงว่างในวิธีเดียวกัน และที่นั่นก็คือ: ในแบบสอบถามกระดาษคุณจะแยกแยะระหว่างไม่มีคำตอบและคำตอบที่ประกอบด้วยสตริงว่างได้อย่างไร
Bernhard Hiller

ถ้าคุณใช้การสืบทอดมันเป็นเรื่องง่ายที่จะพูดif( value === null) { use parent value; } อย่างไรก็ตามถ้าคุณตั้งค่าลูกแม้จะเป็นสตริงที่ว่างเปล่า (เช่นแทนที่ค่าเริ่มต้นที่มีค่าว่างเปล่า) แล้วคุณจะ "สืบทอดค่า" ได้อย่างไร? สำหรับฉันการตั้งค่าเป็นโมฆะจะหมายถึง "ยกเลิกค่านี้ดังนั้นเราจึงรู้ว่าจะใช้ค่าหลัก"
Frank Forte

เนื่องจาก "ลบคุณสมบัติที่ว่างเปล่า" ก็เป็นสาเหตุที่ "หลีกเลี่ยง" a null(เป็นจริงที่nullหลีกเลี่ยงเช่นนี้) ผู้ถามหมายถึง "Return non-null" [วัตถุ] (เช่น: สตริงว่างเปล่าอาร์เรย์ว่าง ฯลฯ ) เมื่อพวกเขา เขียน "หลีกเลี่ยง"
เซเลโพ

คำตอบ:


18

TLDR; ลบคุณสมบัติ null

สิ่งแรกที่ต้องคำนึงถึงคือแอปพลิเคชันที่ขอบของพวกเขาไม่ใช่วัตถุเชิง (หรือฟังก์ชันถ้าโปรแกรมในกระบวนทัศน์นั้น) JSON ที่คุณได้รับไม่ใช่วัตถุและไม่ควรได้รับการปฏิบัติเช่นนี้ มันเป็นเพียงข้อมูลที่มีโครงสร้างซึ่งอาจ (หรืออาจจะไม่) แปลงเป็นวัตถุ โดยทั่วไปไม่ควรเชื่อถือ JSON ที่เข้ามาเป็นวัตถุทางธุรกิจจนกว่าจะได้รับการตรวจสอบความถูกต้องเช่นนี้ ความจริงที่ว่า deserialized ไม่ทำให้ถูกต้อง เนื่องจาก JSON ยังมีข้อ จำกัด ดั้งเดิมเมื่อเทียบกับภาษาแบ็คเอนด์จึงมักจะคุ้มค่าที่จะทำให้DTO ที่จัดแนว JSON สำหรับข้อมูลที่เข้ามา จากนั้นใช้ DTO เพื่อสร้างออบเจ็กต์ทางธุรกิจ (หรือลองผิดพลาด) เพื่อเรียกใช้การทำงานของ API

เมื่อคุณดูที่ JSON เป็นเพียงรูปแบบการส่งข้อมูลจะไม่เหมาะสมกับคุณสมบัติที่ไม่ได้ตั้งค่า น้อยกว่าที่จะส่งข้ามสาย หากภาษาแบ็คเอนด์ของคุณไม่ได้ใช้ค่า null คุณอาจกำหนดค่าตัว deserializer เพื่อให้เกิดข้อผิดพลาด ตัวอย่างเช่นการตั้งค่าทั่วไปของฉันสำหรับ Newtonsoft.Json แปลคุณสมบัติเป็นโมฆะ / หายไปเป็น / จากoptionประเภทF # เท่านั้นและจะเกิดข้อผิดพลาดเป็นอย่างอื่น สิ่งนี้จะให้การเป็นตัวแทนตามธรรมชาติของฟิลด์ที่เป็นตัวเลือก (ที่มีoptionชนิด)

เช่นเคยภาพรวมทำให้คุณไปได้ไกล อาจมีกรณีที่คุณสมบัติเริ่มต้นหรือเป็นโมฆะเหมาะกับที่ดีกว่า แต่ที่สำคัญคืออย่ามองโครงสร้างข้อมูลที่ขอบระบบของคุณเป็นวัตถุทางธุรกิจ วัตถุธุรกิจควรมีการค้ำประกันทางธุรกิจ (เช่นชื่ออย่างน้อย 3 ตัวอักษร) เมื่อสร้างสำเร็จ แต่โครงสร้างข้อมูลที่ดึงออกมาจากสายไม่รับประกันจริง


3
ในขณะที่ serializers ที่ทันสมัยส่วนใหญ่มีฟิลด์ที่เป็นตัวเลือกการละเว้นโมฆะจากการตอบกลับไม่ใช่ความคิดที่ดีเสมอไป ดังนั้นมันเป็นจริงกรณีขึ้นอยู่กับขึ้นอยู่กับวิธีจับห้องสมุดของคุณเป็นอันดับ nullables และไม่ว่าจะได้หรือไม่ (ศักยภาพ) เพิ่มความซับซ้อนของการจัดการ nullables นั้นคือจริงๆประหยัดคุ้มค่ากี่ไบต์ต่อคำขอ คุณต้องทำงานอย่างหนักเพื่อวิเคราะห์กรณีธุรกิจของคุณ
Chris Cirefice

@ChrisCirefice ใช่ฉันเชื่อว่าย่อหน้าสุดท้ายนั้น มีหลายกรณีที่จะใช้กลยุทธ์ที่แตกต่างกัน
Kasey Speakman

ฉันยอมรับว่า JSON ใช้เป็นรูปแบบการส่งข้อมูลเท่านั้นมันไม่ผ่านวัตถุผ่านสายไฟเช่น CORBA ฉันยังยอมรับด้วยว่าสามารถเพิ่มและลบคุณสมบัติได้ การเป็นตัวแทนสามารถเปลี่ยนแปลงการควบคุมสามารถเปลี่ยนแปลงได้โดยเฉพาะอย่างยิ่งในเว็บ
imel96

15

ปรับปรุง:ฉันได้แก้ไขคำตอบเล็กน้อยเพราะอาจนำไปสู่ความสับสน


การไปกับสตริงว่างเปล่าคือหมายเลขที่แน่นอน สตริงว่างยังคงเป็นค่ามันเป็นเพียงแค่ที่ว่างเปล่า nullไม่มีค่าควรจะชี้ให้เห็นการใช้โครงสร้างซึ่งหมายถึงอะไร,

จากมุมมองของนักพัฒนา API มีคุณสมบัติอยู่สองประเภทเท่านั้น:

  • ต้องการ (ต้องมีค่าประเภทเฉพาะและต้องไม่ว่างเปล่า)
  • ตัวเลือก (เหล่านี้อาจมีค่าประเภทเฉพาะของพวกเขา nullแต่ก็อาจจะมี

ทำให้เห็นได้ชัดว่าเมื่อทรัพย์สินมีผลบังคับใช้เช่น มันไม่สามารถเป็นnullไปได้

ในทางกลับกันหากคุณสมบัติที่เป็นตัวเลือกของวัตถุไม่ได้ถูกตั้งค่าและปล่อยว่างไว้ฉันต้องการเก็บไว้ในการตอบกลับด้วยnullค่า จากประสบการณ์ของผมก็จะทำให้มันง่ายขึ้นสำหรับลูกค้า API เพื่อดำเนินการแยกเช่นที่พวกเขาไม่จำเป็นต้องมีการตรวจสอบว่าทรัพย์สินที่มีอยู่จริงหรือไม่เพราะมันมักจะมีและพวกเขาก็สามารถแปลงการตอบสนองต่อพวกเขาเอง DTO รักษาnullค่า เป็นตัวเลือก

การรวม / ลบฟิลด์จากการตอบสนองแบบไดนามิกรวมถึงเงื่อนไขเพิ่มเติมในไคลเอนต์


ไม่ว่าคุณจะเลือกวิธีใดให้แน่ใจว่าคุณเก็บมันไว้อย่างสม่ำเสมอและมีเอกสารครบถ้วน ด้วยวิธีนี้มันไม่สำคัญว่าคุณจะใช้ API ของคุณอย่างไรตราบใดที่พฤติกรรมนั้นสามารถคาดเดาได้


ใช่สตริงว่างคือค่าและฉันใช้nullสำหรับการอ้างอิง การผสมค่ากับการอ้างอิงเป็นหนึ่งในข้อกังวลของฉัน คุณสร้างความแตกต่างของฟิลด์ตัวเลือกด้วยnullจากฟิลด์สตริงที่ไม่ใช่ทางเลือกที่มีnullค่าได้อย่างไร การแยกวิเคราะห์ใหม่ไม่ใช่การทดสอบการมีอยู่ของคุณสมบัติทำให้ parser มีความเปราะบางมากขึ้นหรือไม่
imel96

2
@ imel96 ฟิลด์ที่ไม่จำเป็นต้องไม่เป็นโมฆะ หากสิ่งที่ไม่ใช่ตัวเลือกมันจะต้องมีค่า (ประเภทเฉพาะของมัน)
Andy

3
นี้. ในฐานะผู้บริโภคทั่วไปของ API ฉันเกลียดเมื่อฉันต้องจัดการกับโครงสร้าง "ไดนามิก" กลับมาหาฉันแม้ว่าจะอยู่ในรูปแบบของฟิลด์ตัวเลือกที่ถูกละเว้น (เห็นด้วยมากว่ามีความแตกต่างใหญ่ระหว่าง ZLS และ Null) ฉันยินดีรับค่าว่างตลอดทั้งวันอย่างมีความสุข ในฐานะผู้เขียน API หนึ่งในเป้าหมายของฉันคือทำให้การใช้งานของลูกค้าไม่เจ็บปวดเท่าที่จะเป็นไปได้และนั่นก็หมายถึงการมีโครงสร้างข้อมูลที่คาดหวังไว้เสมอ
jleach

@DavidPacker ดังนั้นหากฉันเข้าใจถูกต้องคุณnullจะใช้เพื่อระบุว่าเป็นตัวเลือก ดังนั้นเมื่อคุณกำหนดวัตถุที่มีคุณสมบัติสตริงที่ไม่จำเป็นและผู้บริโภคไม่มีคุณสมบัตินี้มันจะต้องส่งสตริงว่างสำหรับคุณสมบัตินั้น นั่นถูกต้องใช่ไหม?
imel96

2
@ GregoryNisbet อย่าทำเช่นนั้น ไม่สมเหตุสมผลเลย
Andy

3

null การใช้งานขึ้นอยู่กับการใช้งาน / ภาษา

ในที่สุดตัวเลือกว่าจะใช้หรือไม่nullเป็นค่าแอปพลิเคชันที่ถูกต้องนั้นส่วนใหญ่จะถูกกำหนดโดยแอปพลิเคชันของคุณและภาษาการเขียนโปรแกรม / อินเตอร์เฟส / ขอบ

ในระดับพื้นฐานฉันขอแนะนำให้พยายามใช้ประเภทที่แตกต่างหากมีคลาสที่แตกต่างกันของค่า nullอาจเป็นตัวเลือกหากอินเทอร์เฟซของคุณอนุญาตและมีเพียงสองคลาสของคุณสมบัติที่คุณพยายามแสดง การข้ามคุณสมบัติอาจเป็นตัวเลือกหากส่วนต่อประสานหรือรูปแบบของคุณอนุญาต ประเภทรวมใหม่ (คลาส, วัตถุ, ประเภทข้อความ) อาจเป็นตัวเลือกอื่น

สำหรับตัวอย่างสตริงของคุณหากนี่เป็นภาษาการเขียนโปรแกรมฉันจะถามคำถามสองสามข้อกับตัวเอง

  1. ฉันวางแผนที่จะเพิ่มค่าในอนาคตหรือไม่? ถ้าเป็นเช่นOptionนั้นอาจจะดีกว่าสำหรับการออกแบบส่วนต่อประสานของคุณ
  2. เมื่อใดที่ฉันต้องตรวจสอบความถูกต้องของการโทร Statically? แบบไดนามิกได้อย่างไร ก่อน? หลังจาก? ที่ทั้งหมดหรือไม่ หากภาษาการเขียนโปรแกรมของคุณรองรับให้ใช้ประโยชน์ของการพิมพ์แบบสแตติกเนื่องจากจะช่วยหลีกเลี่ยงจำนวนรหัสที่คุณต้องสร้างเพื่อการตรวจสอบความถูกต้อง Optionอาจกรอกข้อมูลในกรณีนี้ให้ดีที่สุดหากสตริงของคุณไม่สามารถยกเลิกได้ อย่างไรก็ตามคุณอาจจะต้องตรวจสอบอินพุตของผู้ใช้เพื่อหาnullค่าสตริงต่อไปดังนั้นฉันอาจจะเลื่อนกลับไปที่บรรทัดแรกของการตั้งคำถาม: ฉันจะแสดงค่าจำนวนเท่าใด
  3. เป็นnullตัวบ่งชี้ของข้อผิดพลาดโปรแกรมเมอร์ในการเขียนโปรแกรมภาษาของฉันได้อย่างไร น่าเสียดายที่nullมักเป็นค่าเริ่มต้นสำหรับพอยน์เตอร์หรือการอ้างอิงที่ไม่ได้กำหนดค่าเริ่มต้น (หรือไม่ได้กำหนดไว้อย่างชัดเจน) ในบางภาษา คือnullเป็นค่าที่ยอมรับเป็นค่าเริ่มต้นหรือไม่ มีความปลอดภัยเป็นค่าเริ่มต้นหรือไม่ บางครั้งnullบ่งบอกถึงค่าที่ได้รับการจัดสรร ฉันควรให้ตัวบ่งชี้การจัดการหน่วยความจำที่อาจเกิดขึ้นหรือปัญหาการเริ่มต้นในโปรแกรมของพวกเขาให้กับผู้ใช้อินเทอร์เฟซของฉันหรือไม่ โหมดความล้มเหลวของการโทรดังกล่าวเมื่อเผชิญกับปัญหาดังกล่าวคืออะไร ผู้โทรอยู่ในกระบวนการหรือเธรดเดียวกันกับฉันหรือไม่เพื่อให้ข้อผิดพลาดดังกล่าวมีความเสี่ยงสูงต่อแอปพลิเคชันของฉัน

ขึ้นอยู่กับคำตอบของคำถามเหล่านี้คุณอาจสามารถพูดได้ว่าnullอินเทอร์เฟซของคุณเหมาะสมหรือไม่

ตัวอย่างที่ 1

  1. ใบสมัครของคุณมีความสำคัญอย่างยิ่งต่อความปลอดภัย
  2. คุณกำลังใช้การกำหนดค่าเริ่มต้นฮีปบางประเภทเมื่อเริ่มต้นและnullเป็นค่าสตริงที่เป็นไปได้ที่ส่งกลับเมื่อความล้มเหลวในการจัดสรรพื้นที่สำหรับสตริง
  3. มีความเป็นไปได้ที่สตริงดังกล่าวจะกระทบกับส่วนต่อประสานของคุณ

คำตอบ: nullอาจไม่เหมาะสม

เหตุผล: nullในกรณีนี้ใช้เพื่อระบุค่าสองประเภทที่แตกต่างกัน ครั้งแรกอาจเป็นค่าเริ่มต้นซึ่งผู้ใช้อินเทอร์เฟซของคุณอาจต้องการตั้งค่า น่าเสียดายที่ค่าที่สองคือการตั้งค่าสถานะเพื่อระบุว่าระบบของคุณทำงานไม่ถูกต้อง ในกรณีเช่นนี้คุณอาจต้องการล้มเหลวอย่างปลอดภัยที่สุดเท่าที่จะเป็นไปได้ (สิ่งใดก็ตามที่มีความหมายต่อระบบของคุณ)

ตัวอย่างที่ 2

  1. คุณกำลังใช้โครงสร้าง C ซึ่งมีchar *สมาชิก
  2. ระบบของคุณไม่ใช้การจัดสรรฮีปและคุณใช้การตรวจสอบ MISRA
  3. อินเทอร์เฟซของคุณยอมรับโครงสร้างนี้เป็นตัวชี้และตรวจสอบเพื่อให้แน่ใจว่าโครงสร้างไม่ได้ชี้ไปที่ NULL
  4. ค่าเริ่มต้นและค่าที่ปลอดภัยของchar *สมาชิกสำหรับ API ของคุณสามารถระบุได้ด้วยค่าเดียวคือNULL
  5. เมื่อเริ่มต้นโครงสร้างของผู้ใช้ของคุณคุณต้องการให้ผู้ใช้มีความเป็นไปได้ที่จะไม่เริ่มchar *สมาชิกอย่างชัดเจน

คำตอบ: NULLอาจเหมาะสม

เหตุผล: มีโอกาสเล็กน้อยที่โครงสร้างของคุณจะผ่านการNULLตรวจสอบ แต่ไม่ได้กำหนดค่าเริ่มต้น อย่างไรก็ตาม API ของคุณอาจไม่สามารถอธิบายสิ่งนี้ได้เว้นแต่ว่าคุณจะมีการตรวจสอบบางอย่างเกี่ยวกับค่า struct และ / หรือการตรวจสอบช่วงของที่อยู่ของ struct MISRA-C linters อาจช่วยให้ผู้ใช้ API ของคุณโดยการตั้งค่าสถานะการใช้งานของ structs ก่อนเริ่มต้น อย่างไรก็ตามสำหรับchar *สมาชิกหากตัวชี้ไปยังจุดโครงสร้างไปยังโครงสร้างเริ่มต้นNULLเป็นค่าเริ่มต้นของสมาชิกที่ไม่ได้ระบุในการเริ่มต้น struct ดังนั้นNULLอาจทำหน้าที่เป็นค่าเริ่มต้นที่ปลอดภัยสำหรับchar *สมาชิก struct ในแอปพลิเคชันของคุณ

ถ้ามันอยู่ในอินเตอร์เฟสการทำให้เป็นอนุกรมฉันจะถามตัวเองด้วยคำถามต่อไปนี้ว่าจะใช้ null ในสตริงหรือไม่

  1. เป็นnullตัวบ่งชี้ของข้อผิดพลาดด้านลูกค้าที่มีศักยภาพ? สำหรับ JSON ใน JavaScript สิ่งนี้อาจnullไม่เป็นข้อบ่งชี้ถึงความล้มเหลวในการจัดสรร ในจาวาสคริปต์มันถูกใช้เป็นตัวบ่งชี้อย่างชัดเจนว่าไม่มีวัตถุจากการอ้างอิงที่จะตั้งปัญหา อย่างไรก็ตามมีตัวแยกวิเคราะห์ที่ไม่ใช่ javascript และ serializers ที่แมป JSON nullนั้นเป็นnullชนิดเนทีฟ หากเป็นกรณีนี้สิ่งนี้จะเป็นการอภิปรายว่าnullการใช้งานแบบเนทีฟนั้นใช้ได้หรือไม่สำหรับภาษาเฉพาะของคุณตัวแยกวิเคราะห์และตัวรวมกันซีเรียลไลเซอร์
  2. การไม่มีค่าคุณสมบัติอย่างชัดเจนส่งผลกระทบมากกว่าค่าคุณสมบัติเดียวหรือไม่ บางครั้งกnullแสดงว่าคุณมีชนิดข้อความใหม่ทั้งหมด มันอาจจะสะอาดกว่าสำหรับผู้บริโภคในรูปแบบการทำให้เป็นอนุกรมเพื่อระบุประเภทข้อความที่แตกต่างอย่างสิ้นเชิง สิ่งนี้ทำให้มั่นใจได้ว่าการตรวจสอบความถูกต้องและตรรกะของแอปพลิเคชันสามารถแยกได้อย่างชัดเจนระหว่างข้อความสองข้อความที่เว็บอินเตอร์เฟสของคุณมีให้

คำแนะนำทั่วไป

nullไม่สามารถเป็นค่าบนขอบหรืออินเทอร์เฟซที่ไม่รองรับ หากคุณกำลังใช้บางสิ่งบางอย่างที่หลวมอย่างเป็นธรรมชาติในการพิมพ์ค่าของคุณสมบัติ (เช่น JSON) ให้ลองดันสคีมาหรือตรวจสอบความถูกต้องของซอฟต์แวร์ Edge ของผู้บริโภค (เช่นJSON Schema ) หากทำได้ ถ้าเป็นภาษาการเขียนโปรแกรม API ตรวจสอบผู้ใช้ป้อนแบบคงที่ถ้าเป็นไปได้ (ผ่านการพิมพ์) หรือดังเท่าที่จะเหมาะสมในการรันไทม์ (aka ฝึกการเขียนโปรแกรมการป้องกันในการเชื่อมต่อของผู้บริโภคที่หันหน้าไปทาง) ที่สำคัญเอกสารหรือกำหนดขอบจึงไม่มีคำถามว่า:

  • ทรัพย์สินประเภทใดมีมูลค่าที่ยอมรับได้
  • ช่วงของค่าใดที่ถูกต้องสำหรับคุณสมบัติที่ระบุ
  • วิธีการรวมประเภทควรมีโครงสร้าง คุณสมบัติใดที่ต้อง / ควร / สามารถนำเสนอในรูปแบบรวม?
  • ถ้าเป็นคอนเทนเนอร์ประเภทใดมีกี่รายการที่สามารถหรือควรเก็บคอนเทนเนอร์และประเภทของค่าที่เก็บคอนเทนเนอร์คืออะไร
  • คำสั่งใดถ้ามีคุณสมบัติหรืออินสแตนซ์ของชนิดคอนเทนเนอร์หรือการรวมที่ส่งคืน
  • มีผลข้างเคียงอะไรบ้างในการตั้งค่าเฉพาะและผลข้างเคียงของการอ่านค่าเหล่านั้นคืออะไร?

1

ที่นี่การวิเคราะห์ส่วนตัวของฉันของคำถามเหล่านี้ มันไม่ได้รับการสนับสนุนจากหนังสือกระดาษการศึกษาหรืออะไรก็ตามเพียงแค่ประสบการณ์ส่วนตัวของฉัน

สตริงว่างเป็น null

นี่คือไม่ไปสำหรับฉัน อย่าผสมซีแมนทิกส์ของสตริงว่างกับของที่ไม่ได้กำหนดไว้ ในหลายกรณีพวกเขาอาจใช้แทนกันได้อย่างสมบูรณ์แบบ แต่คุณสามารถเรียกใช้ในกรณีที่ไม่ได้กำหนดและกำหนด แต่ว่างเปล่าหมายถึงสิ่งที่แตกต่างกัน

ตัวอย่างที่โง่เง่า: สมมติว่ามีแอตทริบิวต์ที่เก็บคีย์ต่างประเทศและไม่ได้กำหนดแอตทริบิวต์นั้นหรือnullหมายความว่าไม่มีการกำหนดความสัมพันธ์ในขณะที่สตริงว่าง""สามารถเข้าใจได้ว่าเป็นความสัมพันธ์ที่กำหนดไว้และ ID ของเรคคอร์ดต่างประเทศคือสตริงว่าง

ไม่ได้กำหนดไว้ null

นี่ไม่ใช่หัวข้อสีดำหรือสีขาว มีข้อดีข้อเสียของวิธีการทั้งสอง

เพื่อประโยชน์ในการกำหนดnullค่าอย่างชัดเจนมีข้อดีเหล่านี้:

  • ข้อความเหล่านี้อธิบายตัวเองได้มากขึ้นเมื่อคุณได้รับรู้ถึงกุญแจทั้งหมดเพียงแค่ดูข้อความใด ๆ
  • เกี่ยวข้องกับประเด็นก่อนหน้านี้มันง่ายกว่าในการเขียนโค้ดและตรวจจับข้อผิดพลาดในข้อมูลของผู้บริโภค: มันง่ายกว่าที่จะตรวจจับข้อผิดพลาดถ้าคุณดึงกุญแจผิด (อาจสะกดผิดอาจเปลี่ยน API ฯลฯ )

ในการสมมติว่าไม่มีคีย์ที่มีอยู่เท่ากับความหมายของnull:

  • การเปลี่ยนแปลงบางอย่างง่ายกว่าที่จะรองรับ ตัวอย่างเช่นหากเวอร์ชันใหม่ของสกีมาข้อความมีคีย์ใหม่คุณสามารถโค้ดผู้บริโภคของข้อมูลเพื่อทำงานกับคีย์ในอนาคตนี้แม้ว่าผู้ผลิตข้อความจะไม่ได้รับการปรับปรุงและยังไม่ให้บริการข้อมูลนี้
  • ข้อความสามารถ verbose น้อยลงหรือสั้นลง

ในกรณีของ API nullที่มีเสถียรภาพอย่างใดและคุณอย่างละเอียดเอกสารนั้นผมคิดว่ามันเป็นอย่างดีตกลงไปยังรัฐที่สำคัญไม่ได้มีอยู่เท่ากับความหมายของ แต่ถ้ามันยุ่งและยุ่งเหยิงมากขึ้น (อย่างที่มันเป็นบ่อย) ฉันคิดว่าคุณสามารถหลีกเลี่ยงอาการปวดหัวได้หากคุณกำหนดค่าทุกอย่างในทุกข้อความอย่างชัดเจน คือถ้ามีข้อสงสัยฉันมักจะทำตามวิธี verbose

ทุกสิ่งที่กล่าวมาสิ่งสำคัญที่สุด: แสดงเจตนาของคุณอย่างชัดเจนและสอดคล้อง อย่าทำอย่างใดอย่างหนึ่งที่นี่และอีกสิ่งหนึ่งที่นั่น ซอฟต์แวร์ที่คาดการณ์ได้เป็นซอฟต์แวร์ที่ดีกว่า


ตัวอย่างสำหรับการใช้สตริงว่างคือสิ่งที่ฉันหมายถึงโดยรายละเอียดการใช้งานเช่นสมมติว่า API ใช้เพื่อเปิดเผยแถวฐานข้อมูล มันจะสร้างความแตกต่างหรือไม่ถ้าไม่มีฐานข้อมูลที่เกี่ยวข้องและหมดจดสำหรับการถ่ายโอนการแทนวัตถุ?
imel96

ไม่จำเป็นต้องมีรายละเอียดการใช้งาน ตัวอย่างของฉันจริงพูดคุยเกี่ยวกับปลากัดสวยงามซึ่งมีฐานข้อมูลที่เกี่ยวข้อง แต่สิ่งที่ฉันพยายามที่จะอธิบายว่าเป็นสตริงที่ว่างเปล่าไม่ได้เป็นศูนย์ / อะไรnull/ อีกตัวอย่าง: ในเกมจะมีวัตถุเป็นตัวละครและมีแอตทริบิวต์ "พันธมิตร" nullพันธมิตรอย่างชัดเจนหมายความว่าจะมีพันธมิตรที่ไม่ทั้งหมด แต่สามารถเข้าใจได้เป็นมีความเป็นหุ้นส่วนที่มีชื่อเป็น"" ""
bgusach

ฉันโอเคกับการอ้างอิงพันธมิตรที่เป็นโมฆะหมายความว่าไม่มีพันธมิตรและการอ้างอิงไม่ใช่สตริง แต่ชื่อพันธมิตรนั้นเป็นสตริงแม้ว่าคุณจะอนุญาตให้มีค่าว่างเป็นชื่อพันธมิตรคุณจะไม่ตรวจจับค่าว่างนั้นและแทนที่ด้วยสตริงว่างในบางจุดใช่ไหม
imel96

หากไม่มีพันธมิตรฉันจะไม่เปลี่ยนnullสตริงว่าง อาจจะแสดงผลในรูปแบบ แต่ไม่เคยอยู่ในรูปแบบข้อมูล
bgusach

ฉันไม่ได้หมายความว่าไม่มีหุ้นส่วนหุ้นส่วนจะเป็นวัตถุ เป็นพันธมิตรnameที่ฉันพูดถึงคุณจะอนุญาตให้ชื่อพันธมิตรเป็นโมฆะหรือไม่
imel96

1

ฉันจะให้สตริงว่างในสถานการณ์ที่มีสตริงและมันเกิดขึ้นเป็นสตริงว่าง ฉันจะให้ null ในสถานการณ์ที่ฉันต้องการพูดอย่างชัดเจนว่า "ไม่ข้อมูลนี้ไม่ได้มี" และไม่ต้องป้อนรหัสเพื่อพูดว่า "ไม่มีข้อมูลที่นั่นอย่ารบกวน"

คุณตัดสินว่าสถานการณ์ใดสามารถเกิดขึ้นได้ แอปพลิเคชันของคุณมีสตริงว่างหรือไม่ คุณต้องการแยกแยะระหว่างการพูดอย่างชัดเจนว่า "ไม่มีข้อมูล" โดยใช้ null และโดยปริยายโดยไม่มีค่าหรือไม่? คุณควรมีทั้งความเป็นไปได้ (โมฆะและไม่มีคีย์ปัจจุบัน) หากทั้งสองจำเป็นต้องแยกแยะโดยลูกค้า

พึงระลึกไว้ว่านี่คือทั้งหมดที่เกี่ยวกับการส่งข้อมูล สิ่งที่ผู้รับทำกับข้อมูลคือธุรกิจของพวกเขาและพวกเขาจะทำสิ่งที่สะดวกที่สุดสำหรับพวกเขา ผู้รับควรจะสามารถจัดการกับสิ่งที่คุณโยนมัน (อาจจะปฏิเสธข้อมูล) โดยไม่ต้องล้มเหลว

หากไม่มีข้อควรพิจารณาอื่น ๆ ฉันจะส่งสิ่งที่สะดวกที่สุดสำหรับผู้ส่งและบันทึกไว้ ฉันไม่ต้องการส่งค่าที่ขาดไปเพราะนี่เป็นโอกาสที่จะปรับปรุงความเร็วในการเข้ารหัสส่งและแยกวิเคราะห์ JSON


ฉันชอบจุดของคุณใน "ถ้าต้องแยกความแตกต่างจากลูกค้า"
imel96

0

แม้ว่าฉันจะไม่สามารถบอกได้ว่าสิ่งที่ดีที่สุดมันเกือบจะไม่ใช่รายละเอียดการใช้งานที่ง่ายแต่ก็เปลี่ยนโครงสร้างของวิธีที่คุณสามารถโต้ตอบกับตัวแปรนั้นได้

หากบางสิ่งบางอย่างอาจเป็นโมฆะคุณควรปฏิบัติต่อราวกับว่ามันเป็นโมฆะในบางจุดดังนั้นคุณจะมีเวิร์กโฟลว์สองแห่งเสมอหนึ่งรายการเป็นโมฆะหนึ่งรายการสำหรับสตริงที่ถูกต้อง เวิร์กโฟลว์แบบแยกไม่จำเป็นต้องเป็นสิ่งเลวร้ายเนื่องจากมีข้อผิดพลาดเล็กน้อยและการใช้งานเฉพาะกรณีซึ่งคุณสามารถใช้งานได้ แต่มันทำให้รหัสของคุณงงงวย

หากคุณมักจะมีปฏิสัมพันธ์กับสตริงในทางเดียวกันก็อาจจะง่ายขึ้นสำหรับการทำงานเพื่ออยู่ในหัวของคุณ

ดังนั้นเช่นเดียวกับการใด ๆ "สิ่งที่ดีที่สุด" คำถามฉันทิ้งให้อยู่กับคำตอบ: มันขึ้นอยู่กับ หากคุณต้องการแยกเวิร์กโฟลว์ของคุณและจับภาพได้ชัดเจนยิ่งขึ้นเมื่อไม่มีการตั้งค่าบางสิ่งให้ใช้ค่า null หากคุณต้องการให้โปรแกรมทำต่อไปเหมือนเดิมให้ใช้สตริงว่าง สิ่งสำคัญคือคุณมีความสอดคล้องกันเลือกผลตอบแทนร่วมกันและยึดติดกับสิ่งนั้น

พิจารณาว่าคุณกำลังสร้าง API ฉันขอแนะนำให้ติดกับสตริงว่างเนื่องจากมีผู้ใช้น้อยกว่าที่จะชดเชยเพราะในฐานะผู้ใช้ของ API ฉันจะไม่ทราบเหตุผลที่ API ของคุณจะให้ค่าเป็นโมฆะยกเว้นคุณ มีเอกสารที่ดีมากซึ่งผู้ใช้บางคนจะไม่อ่านอยู่ดี


การมี "การแยกเวิร์กโฟลว์" นั้นไม่ดี ให้พูดในด้านการผลิตทุกอย่างสะอาดวิธีสตริงประเภทเพียงคืนstrings ไม่เป็นโมฆะ หาก API ใช้ null ดังนั้น ณ จุดหนึ่งโปรดิวเซอร์ต้องสร้างสิ่งนี้nullเพื่อให้สอดคล้องกับ API จากนั้นผู้บริโภคก็ต้องจัดการnullเช่นกัน แต่ฉันคิดว่าฉันได้สิ่งที่คุณพูดแค่ตัดสินใจและกำหนด API ด้วยสิทธิ์ใช่มั้ย นั่นหมายความว่าไม่มีอะไรผิดปกติกับพวกเขาหรือไม่?
imel96

ใช่สิ่งที่คุณทำใน API ของคุณจะส่งผลกระทบต่อวิธีที่ผู้ใช้จะต้องจัดโครงสร้างรหัสของพวกเขาดังนั้นเมื่อพิจารณาการออกแบบของคุณในแง่ของผู้ใช้ API คุณควรจะสามารถกำหนดวิธีที่ดีที่สุดได้ ท้ายที่สุดก็คือ API ของคุณ เพียงแค่ให้สอดคล้อง มีเพียงคุณเท่านั้นที่สามารถตัดสินใจข้อดีข้อเสียของวิธีการ
Erdrik Ironrose

0

เอกสาร!

TL; DR>

ทำตามที่เห็นสมควร - บางครั้งบริบทที่มันถูกนำมาใช้ ตัวอย่างการเชื่อมโยงตัวแปรไปยัง Oracle SQL: สตริงว่างถูกตีความว่าเป็น NULL

เพียงแค่ฉันจะบอกว่า - ให้แน่ใจว่าคุณเอกสารแต่ละสถานการณ์ที่กล่าวถึง

  • โมฆะ
  • ว่างเปล่า (ว่าง)
  • ไม่มี (ลบออก)

รหัสของคุณอาจทำงานในรูปแบบที่แตกต่างกันไป - จัดทำเอกสารว่าโค้ดของคุณตอบสนองอย่างไร

  • ล้มเหลว (ข้อยกเว้น ฯลฯ ) หรืออาจล้มเหลวในการตรวจสอบความถูกต้อง (อาจเป็นข้อยกเว้นที่ตรวจสอบแล้ว) vs ไม่สามารถจัดการกับสถานการณ์ได้อย่างถูกต้อง (NullPointerException)
  • ให้ค่าเริ่มต้นที่เหมาะสม
  • รหัสพฤติกรรมแตกต่างกัน

จากนั้นนอกจากนั้น - ขึ้นอยู่กับคุณที่จะประพฤติตนอย่างสม่ำเสมอและอาจนำแนวทางปฏิบัติที่ดีที่สุดของคุณมาใช้ เอกสารที่มีพฤติกรรมที่สอดคล้องกัน ตัวอย่าง:

  • ปฏิบัติต่อ Null และ Missing เหมือนเดิม
  • ปฏิบัติกับสตริงที่ว่างเปล่าอย่างนั้น เฉพาะในกรณีที่มีการเชื่อม SQL มันอาจจะถือว่าว่างเปล่า ตรวจสอบให้แน่ใจว่า SQL ของคุณทำงานอย่างสม่ำเสมอและตามที่คาดไว้

ปัญหาคือโดยไม่ต้องจัดการกับข้อกังวลความขัดแย้งเกิดขึ้นค่อนข้างบ่อย พิจารณาในสภาพแวดล้อมของทีมการตัดสินใจจะต้องมีการตัดสินใจของทีมหลายครั้งที่หมายความว่าจะมีการโต้แย้ง เมื่อคุณมีหลายทีมทุกทีมมีสิทธิ์ในการตัดสินใจของตนเอง ฉันเห็น API ที่ฉันสามารถคาดเดาได้เท่านั้นว่ามีการใช้งานโดยทีมต่าง ๆ ที่ไม่เห็นด้วย หากผู้ใดเห็นด้วยกับเรื่องใดเรื่องหนึ่งการบันทึกเป็นเรื่องเล็กน้อย
imel96

0

tl; dr - หากคุณใช้: ให้สอดคล้องในความหมาย

หากคุณรวมnullสิ่งนั้นหมายความว่าอย่างไร มีจักรวาลของสิ่งที่มันอาจหมายถึง ค่าเดียวนั้นไม่เพียงพอที่จะเป็นตัวแทนของค่าที่หายไปหรือไม่ทราบ (และนี่เป็นเพียงสองของความเป็นไปได้มากมาย: เช่นหายไป - มันถูกวัด แต่เรายังไม่รู้ว่ามันไม่ทราบไม่ทราบ - เราไม่ได้พยายามวัด มัน.)

ในตัวอย่างที่ฉันพบเมื่อเร็ว ๆ นี้เขตข้อมูลอาจว่างเปล่าเนื่องจากไม่มีการรายงานเพื่อปกป้องความเป็นส่วนตัวของใครบางคน แต่เป็นที่รู้จักกันที่ด้านข้างของผู้ส่งไม่เป็นที่รู้จักที่ด้านข้างของผู้ส่ง และสิ่งเหล่านี้มีความสำคัญต่อผู้รับ ดังนั้นโดยปกติแล้วค่าหนึ่งค่าไม่เพียงพอ

ด้วยสมมติฐานของโลกที่เปิดกว้าง (คุณไม่รู้เกี่ยวกับสิ่งที่ไม่ได้ระบุไว้) คุณจะทิ้งมันไว้และมันอาจเป็นอะไรก็ได้ ด้วยข้อสันนิษฐานของโลกที่ปิด (สิ่งที่ไม่ได้ระบุเป็นเท็จตัวอย่างเช่นใน SQL) คุณควรระบุให้ชัดเจนว่าnullหมายถึงอะไรและสอดคล้องกับคำจำกัดความที่คุณสามารถ ...

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.