คำถามของคุณ.
แต่จากความไร้เดียงสาของฉันให้ฉันกรีดร้อง - บางครั้งคุณค่าอาจหายไปอย่างมีความหมาย!
ขึ้นเครื่องอย่างเต็มที่กับคุณที่นั่น อย่างไรก็ตามมีคำเตือนบางอย่างที่ฉันจะเข้าไปภายในไม่กี่วินาที แต่แรก:
Nulls นั้นชั่วร้ายและควรหลีกเลี่ยงเมื่อเป็นไปได้
ฉันคิดว่านี่เป็นคำที่เจตนาดี แต่มากเกินไป
Nulls ไม่ใช่ความชั่วร้าย พวกเขาไม่ได้เป็น antipattern พวกเขาไม่ใช่สิ่งที่ต้องหลีกเลี่ยงค่าใช้จ่ายทั้งหมด อย่างไรก็ตามค่า null มีแนวโน้มที่จะเกิดข้อผิดพลาด (จากความล้มเหลวในการตรวจสอบค่าว่าง)
แต่ฉันไม่เข้าใจว่าการตรวจสอบความล้มเหลวของ null เป็นวิธีการใดที่พิสูจน์ว่า null นั้นผิดที่จะใช้
ถ้า null เป็นความชั่วร้ายดังนั้นเป็นดัชนีอาร์เรย์และพอยน์เตอร์ C ++ พวกเขาไม่. พวกมันยิงได้ง่ายด้วยเท้า แต่ก็ไม่ควรที่จะหลีกเลี่ยงค่าใช้จ่ายทั้งหมด
สำหรับส่วนที่เหลือของคำตอบนี้ฉันจะปรับความตั้งใจของ "โมฆะคือความชั่วร้าย" กับโมฆะที่เหมาะสมยิ่งขึ้น " ควรได้รับการจัดการอย่างรับผิดชอบ "
ทางออกของคุณ
ในขณะที่ฉันเห็นด้วยกับความคิดเห็นของคุณเกี่ยวกับการใช้ null เป็นกฎสากล ฉันไม่เห็นด้วยกับการใช้ null ในกรณีนี้โดยเฉพาะ
เพื่อสรุปข้อเสนอแนะด้านล่าง: คุณเข้าใจผิดวัตถุประสงค์ของการสืบทอดและความหลากหลาย ในขณะที่ข้อโต้แย้งของคุณที่จะใช้เป็นโมฆะมีเหตุผล แต่ "หลักฐาน" ของคุณเพิ่มเติมว่าทำไมวิธีอื่น ๆ ที่ไม่ดีถูกสร้างขึ้นในทางที่ผิดของการสืบทอดการแสดงคะแนนของคุณค่อนข้างไม่เกี่ยวข้องกับปัญหา null
การอัปเดตส่วนใหญ่จะมีผู้เล่นเชื่อมโยงกับพวกเขาตามปกติ - หลังจากทั้งหมดคุณจำเป็นต้องรู้ว่าผู้เล่นคนใดที่ทำในเทิร์นนี้ อย่างไรก็ตามการอัปเดตบางอย่างไม่สามารถเชื่อมโยง Player ได้อย่างมีความหมาย
หากการอัปเดตเหล่านี้มีความหมายแตกต่างกัน (ซึ่งเป็น) คุณจำเป็นต้องมีการอัพเดตสองแบบแยกกัน
พิจารณาข้อความเช่น คุณมีข้อความแสดงข้อผิดพลาดและข้อความแชท IM แต่ในขณะที่พวกเขาอาจมีข้อมูลที่คล้ายกันมาก (ข้อความสตริงและผู้ส่ง) พวกเขาไม่ได้ทำงานในลักษณะเดียวกัน ควรใช้แยกต่างหากเป็นคลาสอื่น
สิ่งที่คุณทำอยู่ในขณะนี้คือการแยกแยะความแตกต่างระหว่างการอัปเดตสองประเภทอย่างมีประสิทธิภาพโดยยึดตามค่า null-ness ของคุณสมบัติ Player ซึ่งเทียบเท่ากับการตัดสินใจเลือกระหว่างข้อความ IM และข้อความแสดงข้อผิดพลาดตามการมีอยู่ของรหัสข้อผิดพลาด มันใช้งานได้ แต่ไม่ใช่วิธีที่ดีที่สุด
- ตอนนี้โค้ด JS จะได้รับวัตถุที่ไม่มีผู้เล่นเป็นคุณสมบัติที่กำหนดซึ่งเหมือนกับว่ามันเป็นโมฆะเนื่องจากทั้งสองกรณีจำเป็นต้องตรวจสอบว่ามีค่าหรือไม่อยู่;
การโต้เถียงของคุณขึ้นอยู่กับ misues ของความหลากหลาย หากคุณมีวิธีการซึ่งผลตอบแทนที่GameUpdate
วัตถุนั้นโดยทั่วไปไม่ควรเคยสนใจที่จะแยกความแตกต่างระหว่างGameUpdate
, หรือ PlayerGameUpdate
NewlyDevelopedGameUpdate
ความต้องการชั้นฐานที่จะมีการทำสัญญาการทำงานได้อย่างเต็มที่คือคุณสมบัติที่มีการกำหนดไว้ในชั้นฐานและไม่อยู่ในชั้นเรียนมา (ที่ถูกกล่าวว่าค่าของคุณสมบัติฐานเหล่านี้สามารถของหลักสูตรจะถูกแทนที่ในชั้นเรียนที่ได้รับ)
สิ่งนี้จะทำให้การโต้แย้งโต้แย้งของคุณ ในทางปฏิบัติคุณไม่ควรสนใจว่าGameUpdate
วัตถุของคุณมีหรือไม่มีผู้เล่น หากคุณพยายามเข้าถึงPlayer
คุณสมบัติของ a แสดงGameUpdate
ว่าคุณทำสิ่งที่ไม่ถูกต้อง
ภาษาที่พิมพ์เช่น C # จะไม่อนุญาตให้คุณลองและเข้าถึงPlayer
คุณสมบัติของ a GameUpdate
เพราะGameUpdate
เพียงไม่มีคุณสมบัติ Javascript มีความเข้มงวดมากขึ้นในแนวทางของมัน (และไม่จำเป็นต้องมีการคอมไพล์ล่วงหน้า) ดังนั้นจึงไม่ต้องกังวลที่จะแก้ไขคุณและทำให้มันระเบิดในรันไทม์แทน
- หากมีการเพิ่มฟิลด์ nullable อื่นลงในคลาส GameUpdate ฉันจะต้องสามารถใช้การสืบทอดหลาย ๆ อันเพื่อดำเนินการต่อด้วยดีไซน์นี้ - แต่ MI นั้นชั่วร้ายในสิทธิ์ของตนเอง (ตามโปรแกรมเมอร์ที่มีประสบการณ์มากกว่า) และที่สำคัญกว่า C # ไม่ มีดังนั้นฉันไม่สามารถใช้งานได้
คุณไม่ควรสร้างคลาสขึ้นอยู่กับการเพิ่มคุณสมบัติที่ไม่สามารถใช้ได้ คุณควรสร้างคลาสตามการปรับปรุงเกมที่มีลักษณะเฉพาะ
วิธีหลีกเลี่ยงปัญหาเกี่ยวกับ null โดยทั่วไปได้อย่างไร
ฉันคิดว่ามันเกี่ยวข้องกับการทำอย่างละเอียดเกี่ยวกับวิธีที่คุณสามารถแสดงถึงการขาดคุณค่า นี่คือชุดของการแก้ปัญหา (หรือแนวทางที่ไม่ดี) โดยไม่คำนึงถึงลำดับ
1. ใช้ค่า null อย่างไรก็ตาม
นี่เป็นวิธีที่ง่ายที่สุด อย่างไรก็ตามคุณกำลังลงทะเบียนเพื่อรับการตรวจสอบโมฆะตันและ (เมื่อไม่สามารถทำได้) การแก้ไขปัญหาข้อยกเว้นการอ้างอิงโมฆะ
2. ใช้ค่าที่ไม่มีความหมายเป็นโมฆะ
ตัวอย่างง่ายๆที่นี่คือindexOf()
:
"abcde".indexOf("b"); // 1
"abcde".indexOf("f"); // -1
แทนที่จะคุณจะได้รับnull
-1
ในระดับเทคนิคนี่เป็นค่าจำนวนเต็มที่ถูกต้อง อย่างไรก็ตามค่าลบเป็นคำตอบที่ไร้สาระเนื่องจากดัชนีคาดว่าจะเป็นจำนวนเต็มบวก
เหตุผลนี้สามารถใช้ได้เฉพาะกรณีที่ประเภทส่งคืนอนุญาตให้มีค่าที่เป็นไปได้มากกว่าที่จะสามารถส่งคืนได้อย่างมีความหมาย (indexOf = จำนวนเต็มบวก; int = จำนวนเต็มบวกและลบ)
สำหรับประเภทอ้างอิงคุณยังสามารถใช้หลักการนี้ได้ ตัวอย่างเช่นหากคุณมีเอนทิตีที่มี ID จำนวนเต็มคุณสามารถส่งคืนวัตถุจำลองด้วยการตั้งค่า ID เป็น -1 ซึ่งตรงข้ามกับค่าว่าง
คุณเพียงแค่ต้องกำหนด "รัฐจำลอง" ซึ่งคุณสามารถวัดได้ว่าวัตถุนั้นใช้งานได้จริงหรือไม่
โปรดทราบว่าคุณไม่ควรพึ่งพาค่าสตริงที่กำหนดไว้ล่วงหน้าหากคุณไม่ได้ควบคุมค่าสตริง คุณอาจจะพิจารณาการตั้งชื่อของผู้ใช้เพื่อ "null" เมื่อคุณต้องการที่จะกลับวัตถุที่ว่างเปล่าแต่คุณจะพบปัญหาเมื่อคริส Null ลงนามขึ้นสำหรับการให้บริการของคุณ
3. โยนข้อยกเว้นแทน
ไม่เพียงแค่ไม่มี. ไม่ควรมีข้อยกเว้นสำหรับการไหลแบบลอจิคัล
ที่ถูกกล่าวว่ามีบางกรณีที่คุณไม่ต้องการซ่อนข้อยกเว้น (nullreference) แต่แสดงข้อยกเว้นที่เหมาะสม ตัวอย่างเช่น:
var existingPerson = personRepository.GetById(123);
สิ่งนี้สามารถขว้างPersonNotFoundException
(หรือคล้ายกัน) เมื่อไม่มีบุคคลใดที่มี ID 123
เห็นได้ชัดว่านี่เป็นที่ยอมรับได้เฉพาะกรณีที่ไม่พบรายการทำให้ไม่สามารถทำการประมวลผลต่อไปได้ หากไม่พบรายการที่เป็นไปได้และโปรแกรมประยุกต์ที่สามารถดำเนินการต่อแล้วคุณไม่ควรโยนข้อยกเว้น ฉันไม่สามารถความเครียดนี้พอ