ฉันควรยอมรับคอลเลกชันที่ว่างเปล่าในวิธีการของฉันที่ทำซ้ำมากกว่าพวกเขา


40

ฉันมีวิธีการที่ตรรกะทั้งหมดจะดำเนินการภายในวง foreach ที่ iterates มากกว่าพารามิเตอร์ของวิธีการ:

public IEnumerable<TransformedNode> TransformNodes(IEnumerable<Node> nodes)
{
    foreach(var node in nodes)
    {
        // yadda yadda yadda
        yield return transformedNode;
    }
}

ในกรณีนี้การส่งคอลเล็กชันว่างเปล่าจะส่งผลให้เกิดคอลเล็กชันที่ว่างเปล่า แต่ฉันสงสัยว่ามันไม่ฉลาด

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

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


43
คุณแน่ใจหรือไม่ว่าสมมติฐานของคุณ "ถ้าใครบางคนกำลังเรียกวิธีนี้พวกเขาตั้งใจจะส่งผ่านข้อมูลใน" ถูกต้องหรือไม่ บางทีพวกเขาอาจจะผ่านสิ่งที่พวกเขามีอยู่เพื่อทำงานกับผลลัพธ์
SpaceTrucker

7
BTW: เมธอด "transform" ของคุณมักจะเรียกว่า "map" แม้ว่าใน. NET (และ SQL ซึ่งเป็นที่ที่. NET ได้ชื่อมาจาก) มันมักเรียกว่า "select" "การแปลง" คือสิ่งที่ C ++ เรียกมัน แต่นั่นไม่ใช่ชื่อสามัญที่อาจรู้จัก
Jörg W Mittag

25
ฉันจะโยนถ้าคอลเล็กชันเป็นnullแต่ไม่ว่างเปล่า
CodesInChaos

21
@NickUdell - ฉันผ่านคอลเลกชันที่ว่างเปล่าในรหัสของฉันตลอดเวลา มันง่ายกว่าสำหรับรหัสที่จะทำงานแบบเดียวกันกับการเขียนตรรกะการแยกสาขาแบบพิเศษสำหรับกรณีที่ฉันไม่สามารถเพิ่มอะไรลงในคอลเลกชันของฉันก่อนที่จะดำเนินการต่อไป
theMayer

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

คำตอบ:


175

วิธีการยูทิลิตี้ไม่ควรทิ้งในคอลเลกชันที่ว่างเปล่า ลูกค้า API ของคุณจะเกลียดคุณ

คอลเลกชันสามารถว่างเปล่า; "คอลเลกชันที่ต้องไม่ว่างเปล่า" เป็นแนวคิดที่เป็นสิ่งที่ยากมากในการทำงานกับ

การแปลงคอลเล็กชันที่ว่างเปล่ามีผลลัพธ์ที่ชัดเจน: การรวบรวมที่ว่างเปล่า (คุณอาจบันทึกขยะด้วยการส่งคืนพารามิเตอร์เอง)

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

วิธีการยูทิลิตี้ควรมุ่งมั่นที่จะเป็นอิสระในปัจจัยการผลิตของพวกเขาและอนุรักษ์นิยมในผลลัพธ์ของพวกเขา

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


14
+1 - (มากกว่านี้ถ้าทำได้) ฉันอาจจะไปไกลถึงขนาดรวมตัวกันnullในคอลเลกชันที่ว่างเปล่า ฟังก์ชั่นที่มีข้อ จำกัด โดยนัยคือความเจ็บปวด
Telastyn

6
"ไม่คุณไม่ควร" ... ไม่ควรยอมรับพวกเขาหรือไม่ควรทิ้งข้อยกเว้น?
Ben Aaronson

16
@Andy - เหล่านั้นจะไม่เป็นยูทิลิตี้วิธีแม้ว่า พวกเขาต้องการวิธีการทางธุรกิจหรือพฤติกรรมที่เป็นรูปธรรมคล้ายกัน
Telastyn

38
ฉันไม่คิดว่าการรีไซเคิลคอลเล็กชันที่ว่างเปล่าเพื่อการส่งคืนเป็นความคิดที่ดี คุณบันทึกหน่วยความจำเพียงเล็กน้อยเท่านั้น และอาจส่งผลให้เกิดพฤติกรรมที่ไม่คาดคิดในผู้โทร ตัวอย่างที่วางแผนไว้เล็กน้อย: Populate1(input); output1 = TransformNodes(input); Populate2(input); output2 = TransformNodes(input); หาก Populate1 ปล่อยให้คอลเลกชันว่างเปล่าและคุณส่งคืนสำหรับการเรียก TransformNode ครั้งแรกเอาต์พุต 1 และอินพุตจะเป็นคอลเล็กชันเดียวกันและเมื่อ Populaten2 ถูกเรียกถ้ามันใส่โหนดในคอลเล็กชันที่คุณต้องการ ชุดของอินพุตในเอาต์พุต 2
Dan Neely

6
@Andy ถึงกระนั้นถ้าอาร์กิวเมนต์ไม่ควรว่างเปล่า - ถ้าเป็นข้อผิดพลาดที่ไม่มีข้อมูลในการประมวลผล - จากนั้นฉันรู้สึกว่าเป็นความรับผิดชอบของผู้โทรที่จะตรวจสอบเรื่องนี้เมื่อมีการเรียงอาร์กิวเมนต์นั้น มันไม่เพียง แต่ทำให้วิธีนี้สวยงามยิ่งขึ้นเท่านั้น แต่ยังหมายความว่าเราสามารถสร้างข้อความแสดงข้อผิดพลาดที่ดีขึ้น (บริบทที่ดีกว่า) และยกระดับขึ้นในวิธีที่ล้มเหลว มันไม่สมเหตุสมผลสำหรับคลาสดาวน์สตรีมเพื่อตรวจสอบค่าคงที่ของผู้โทร ...
Andrzej Doyle

26

ฉันเห็นคำถามสำคัญสองข้อที่กำหนดคำตอบสำหรับสิ่งนี้:

  1. ฟังก์ชั่นของคุณสามารถคืนสิ่งที่มีความหมายและมีเหตุผลได้เมื่อผ่านคอลเลกชันที่ว่างเปล่า (รวมถึงโมฆะ ) หรือไม่?
  2. รูปแบบการเขียนโปรแกรมทั่วไปในแอปพลิเคชัน / ห้องสมุด / ทีมนี้คืออะไร (โดยเฉพาะ FP เป็นอย่างไรบ้าง?)

1. ผลตอบแทนที่มีความหมาย

เป็นหลักหากคุณสามารถคืนสิ่งที่มีความหมายแล้วอย่าโยนข้อยกเว้น ให้ผู้โทรจัดการกับผลลัพธ์ ดังนั้นถ้าฟังก์ชั่นของคุณ ...

  • นับจำนวนองค์ประกอบในคอลเลกชันคืน 0 นั่นเป็นเรื่องง่าย
  • ค้นหาองค์ประกอบที่ตรงกับเกณฑ์เฉพาะคืนชุดว่าง โปรดอย่าโยนอะไรเลย ผู้โทรอาจมีคอลเลกชันขนาดใหญ่ซึ่งบางอันไม่มีข้อมูล ผู้เรียกต้องการองค์ประกอบที่ตรงกันในคอลเลกชันใด ๆ ข้อยกเว้นเท่านั้นทำให้ชีวิตของผู้โทรยากขึ้น
  • กำลังมองหาเกณฑ์ที่ใหญ่ที่สุด / เล็กที่สุด / ดีที่สุด - พอดีกับเกณฑ์ในรายการ อุ่ย ทั้งนี้ขึ้นอยู่กับคำถามสไตล์คุณอาจโยนข้อยกเว้นที่นี่หรือคุณอาจจะกลับnull ฉันเกลียด null (มากคน FP) แต่มันมีความหมายเนื้อหาที่นี่และช่วยให้คุณสำรองข้อยกเว้นสำหรับข้อผิดพลาดที่ไม่คาดคิดในรหัสของคุณเอง หากผู้โทรไม่ตรวจสอบค่า null ข้อยกเว้นที่ค่อนข้างชัดเจนจะส่งผลต่อไป แต่คุณปล่อยให้พวกเขา
  • ขอให้รายการ nth ในคอลเลกชันหรือรายการแรก / สุดท้าย n นี่เป็นกรณีที่ดีที่สุดสำหรับข้อยกเว้นและเป็นกรณีที่มีโอกาสน้อยที่จะทำให้เกิดความสับสนและยากสำหรับผู้โทร เคสยังสามารถถูกทำให้เป็นโมฆะได้หากคุณและทีมของคุณถูกใช้เพื่อตรวจสอบเหตุผลทั้งหมดที่ให้ไว้ในจุดก่อนหน้านี้ แต่นี่เป็นกรณีที่ถูกต้องที่สุดสำหรับการขว้างข้อยกเว้นDudeYou Know YouShouldCheckTheSizeFirst หากสไตล์ของคุณใช้งานได้ดีขึ้นก็จะทำให้nullหรืออ่านคำตอบสไตล์ของฉัน

โดยทั่วไปอคติ FP ของฉันบอกฉันว่า "คืนสิ่งที่มีความหมาย" และnullอาจมีความหมายที่ถูกต้องในกรณีนี้

2. สไตล์

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

F # เป็นที่ที่เด็ก ๆ . Net ทุกคนทำสิ่งนี้ แต่ C # ไม่ สนับสนุนรูปแบบนี้

TL; DR

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


"พอดีที่สุด" ฯลฯ : คุณอาจมีวิธีการค้นหาวัตถุที่เหมาะสมที่สุดในคอลเลกชันที่ตรงกับเกณฑ์บางอย่าง วิธีการนั้นจะมีปัญหาแบบเดียวกันสำหรับคอลเล็กชั่นที่ไม่ว่างเปล่าเนื่องจากไม่มีสิ่งใดที่เหมาะสมกับเกณฑ์ดังนั้นไม่จำเป็นต้องกังวลเกี่ยวกับการเลือกที่ว่างเปล่า
gnasher729

1
ไม่นั่นคือเหตุผลที่ฉันพูดว่า "เหมาะสมที่สุด" ไม่ใช่ "จับคู่"; วลีนั้นหมายถึงการประมาณที่ใกล้เคียงที่สุดไม่ใช่การจับคู่ที่ตรงกัน ตัวเลือกที่ใหญ่ที่สุด / น้อยที่สุดควรเป็นเงื่อนงำ หากได้รับการขอเฉพาะ“ ดีที่สุด” เท่านั้นการรวบรวมใด ๆ ที่มีสมาชิกตั้งแต่ 1 คนขึ้นไปควรจะสามารถส่งคืนสมาชิกได้ หากมีสมาชิกเพียงคนเดียวนั่นคือแบบที่ดีที่สุด
itsbruce

1
กลับ "null" ในกรณีส่วนใหญ่แย่กว่านั้นโยนข้อยกเว้น อย่างไรก็ตามการส่งคืนคอลเลกชันที่ว่างเปล่านั้นมีความหมาย
เอียน

1
ไม่ใช่ถ้าคุณต้องส่งคืนรายการเดียว (ต่ำสุด / สูงสุด / หัว / ท้าย) สำหรับ null อย่างที่ฉันบอกว่าฉันเกลียดมัน (และชอบภาษาที่ไม่มีมัน) แต่ในกรณีที่ภาษามีคุณต้องจัดการกับมันและรหัสที่จัดการมัน มันอาจจะเหมาะสม
itsbruce

ตัวอย่างของคุณไม่มีส่วนเกี่ยวข้องกับอินพุตว่าง พวกเขาเป็นเพียงกรณีพิเศษของสถานการณ์ที่คำตอบอาจจะ "ไม่มีอะไร" ซึ่งในทางกลับกันควรตอบคำถามของ OP เกี่ยวกับวิธีการ "จัดการ" คอลเลกชันที่ว่างเปล่า
djechlin

18

เช่นเคยมันขึ้นอยู่กับ

มันไม่สำคัญว่าคอลเลกชันที่ว่างเปล่า?
รหัสการจัดการคอลเลกชันส่วนใหญ่อาจจะพูดว่า "ไม่" คอลเลกชันสามารถมีรายการจำนวนเท่าใดก็ได้ในนั้นรวมถึงศูนย์

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

ยืมตรรกะการทดสอบบางส่วนจากโลกของฐานข้อมูล: ทดสอบรายการศูนย์หนึ่งรายการและสองรายการ กรณีนี้เหมาะสำหรับกรณีที่สำคัญที่สุด (ล้างเงื่อนไขการเข้าร่วมด้านในหรือคาร์ทีเซียนที่เกิดขึ้นไม่ดี)


และถ้ามันไม่ถูกต้องที่จะไม่มีรายการในคอลเลคชั่นการโต้แย้งก็ไม่ควรเป็นjava.util.Collectionแต่com.foo.util.NonEmptyCollectionคลาสที่กำหนดเองที่สามารถรักษาค่าคงที่นี้ไว้ได้อย่างสม่ำเสมอและป้องกันไม่ให้คุณเข้าสู่สถานะที่ไม่ถูกต้องเพื่อเริ่มต้น
Andrzej Doyle

3
คำถามนี้ถูกแท็ก [c #]
Nick Udell

@NickUdell C # ไม่รองรับการเขียนโปรแกรม Object Oriented หรือแนวคิดของเนมสเปซที่ซ้อนกันหรือไม่ TIL
John Dvorak

2
มันทำ ความคิดเห็นของฉันเป็นคำชี้แจงเนื่องจาก Andrzej ต้องสับสน (เพราะเหตุใดพวกเขาจะพยายามระบุชื่อที่มีภาษาอื่นสำหรับคำถามที่คำถามนี้ไม่ได้อ้างอิง)
Nick Udell

-1 สำหรับการเน้น "มันขึ้นอยู่กับ" มากกว่า "เกือบแน่นอนใช่" ไม่ตลก - การสื่อสารสิ่งผิดจะสร้างความเสียหายที่นี่
djechlin

11

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

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

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


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

@AAA - เห็นได้ชัดว่าเราไม่ได้เขียนหนังสือเกี่ยวกับวิธีการออกแบบซอฟต์แวร์ที่นี่ แต่ฉันไม่คิดว่ามันจะเป็นคำแนะนำที่ไม่ดีเลยถ้าคุณเข้าใจสิ่งที่ฉันพูดจริงๆ ประเด็นของฉันคือการป้อนข้อมูลที่ไม่ดีจะสร้างผลลัพธ์ที่ไม่ชัดเจนหรือมีข้อผิดพลาดคุณต้องส่งข้อยกเว้น ในกรณีที่ผลลัพธ์สามารถคาดเดาได้ทั้งหมด (เช่นกรณีที่นี่) จากนั้นการโยนข้อยกเว้นจะเป็นการกำหนดเอง กุญแจสำคัญคือไม่ต้องตัดสินใจโดยพลการในโปรแกรมของคุณเนื่องจากเป็นสิ่งที่พฤติกรรมที่ไม่สามารถคาดเดาได้มาจาก
theMayer

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

10

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

input.split("\\D")
.filterNot (_.isEmpty)
.map (_.toInt)
.filter (x => x >= 1000 && x <= 9999)

ก่อนอื่นคุณแยกสตริงด้วยตัวเลขที่ไม่ใช่ตัวเลขกรองสตริงว่างแปลงสตริงเป็นจำนวนเต็มจากนั้นกรองเพื่อเก็บเฉพาะตัวเลขสี่หลัก ฟังก์ชั่นของคุณอาจจะmap (_.toInt)อยู่ในท่อ

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

แน่นอนว่าสมมติว่ารายการเอาต์พุตว่างไม่มีความหมายมากกว่าหนึ่งรายการ หากคุณต้องการแยกความแตกต่างระหว่างเอาต์พุตว่างที่เกิดจากอินพุตว่างและอีกอันเกิดจากการแปลงเองนั่นจะเปลี่ยนแปลงสิ่งต่าง ๆ โดยสิ้นเชิง


+1 สำหรับตัวอย่างที่มีประสิทธิภาพมาก (ขาดคำตอบที่ดีอื่น ๆ )
djechlin

2

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

1) วิธีการควรยกเว้นเมื่อไม่สามารถดำเนินการต่อ: ไม่สามารถทำงานที่ได้รับมอบหมายหรือคืนค่าที่เหมาะสม

2) วิธีการควรตรวจจับข้อยกเว้นเมื่อสามารถดำเนินการต่อได้แม้จะล้มเหลว

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

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


1

TransformNodesวิธีการตั้งชื่อ ในกรณีของคอลเลกชันที่ว่างเปล่าเป็นอินพุตการเรียกคืนคอลเลกชันที่ว่างเปล่าเป็นธรรมชาติและใช้งานง่ายและทำให้ความรู้สึกทางคณิตศาสตร์นายอำเภอ

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

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


Maxของอะไรมักจะเป็นลบอนันต์
djechlin

0

ลองย้อนกลับไปและใช้ตัวอย่างที่แตกต่างกันซึ่งคำนวณค่าเฉลี่ยเลขคณิตของอาร์เรย์ของค่า

หากอาร์เรย์อินพุตว่างเปล่า (หรือ null) คุณสามารถทำตามคำขอของผู้โทรได้หรือไม่? ไม่ตัวเลือกของคุณคืออะไร? คุณทำได้:

  • ปัจจุบัน / ส่งคืน / โยนข้อผิดพลาด ใช้แบบแผน codebase ของคุณสำหรับคลาสของข้อผิดพลาดนั้น
  • เอกสารที่ค่าเช่นศูนย์จะถูกส่งกลับ
  • เอกสารที่จะส่งคืนค่าที่ไม่ถูกต้องที่กำหนด (เช่น NaN)
  • เอกสารที่จะส่งคืนค่าเวทย์มนตร์ (เช่น min หรือ max สำหรับประเภทหรือค่าที่บ่งบอกถึงความหวังบางอย่าง)
  • ประกาศผลที่ไม่ได้ระบุ
  • ประกาศการกระทำที่ไม่ได้กำหนด
  • เป็นต้น

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

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

มันสำคัญมากที่รหัสของคุณจะต้องสอดคล้องกันในการจัดการข้อผิดพลาดของคลาสเหล่านี้

ประเภทถัดไปคือการตัดสินใจว่าห้องสมุดของคุณจัดการกับคำขอไร้สาระได้อย่างไร เดินทางกลับไปตัวอย่างคล้ายกับคุณ - bool FileExistsAtPath(String)ขอใช้ฟังก์ชั่นซึ่งเป็นตัวกำหนดว่าไฟล์ที่มีอยู่ในเส้นทางที่: หากไคลเอนต์ผ่านสตริงว่างคุณจะจัดการสถานการณ์นี้ได้อย่างไร อาร์เรย์ว่างหรือโมฆะจะถูกส่งไปที่void SaveDocuments(Array<Document>)ใด ตัดสินใจสำหรับ library / codebase ของคุณและสอดคล้องกัน. ฉันบังเอิญพิจารณาข้อผิดพลาดของกรณีเหล่านี้และห้ามไม่ให้ลูกค้าส่งคำขอที่ไร้สาระด้วยการตั้งค่าสถานะเป็นข้อผิดพลาด (ผ่านการยืนยัน) บางคนจะต่อต้านความคิด / การกระทำนั้นอย่างยิ่ง ฉันพบว่าการตรวจจับข้อผิดพลาดนี้มีประโยชน์มาก มันเป็นเรื่องที่ดีมากสำหรับการค้นหาปัญหาในโปรแกรม - ด้วยท้องที่ที่ดีสำหรับโปรแกรมที่ละเมิด โปรแกรมมีความชัดเจนและถูกต้องมาก (พิจารณาวิวัฒนาการของ codebase ของคุณ) และอย่าเผาวงจรภายในฟังก์ชั่นที่ไม่ทำอะไรเลย วิธีนี้มีขนาดเล็กลง / สะอาดกว่าและโดยทั่วไปการตรวจสอบจะถูกส่งไปยังสถานที่ที่อาจมีปัญหา


6
สำหรับตัวอย่างสุดท้ายของคุณไม่ใช่หน้าที่ของฟังก์ชั่นในการพิจารณาว่าอะไรไร้สาระ ดังนั้นสตริงว่างควรส่งคืนค่าเท็จ แท้จริงแล้วนั่นคือวิธีการที่แน่นอนFile.Existsใช้
theMayer

@ rmayer06 มันเป็นงานของมัน ฟังก์ชั่นอ้างอิงอนุญาตให้เป็นโมฆะ, สตริงว่าง, ตรวจสอบอักขระที่ไม่ถูกต้องในสตริง, ทำการตัดสายอักขระ, อาจจำเป็นต้องทำการเรียกระบบไฟล์, อาจจำเป็นต้องค้นหาสภาพแวดล้อม, ฯลฯ สิ่งอำนวยความสะดวกที่ซ้ำซ้อน ค่าใช้จ่ายสูงและแน่นอนพวกเขาเบลอบรรทัดของความถูกต้อง (IMO) ฉันเคยเห็นif (!FileExists(path)) { ...create it!!!... }ข้อบกพร่องมากมาย - ซึ่งหลายคนจะถูกจับได้ก่อนที่จะส่งมอบความถูกต้องไม่เบลอ
justin

2
ฉันจะเห็นด้วยกับคุณถ้าชื่อของฟังก์ชั่นเป็น File.ThrowExceptionIfPathIsInvalid แต่ใครในใจที่ถูกต้องของพวกเขาจะเรียกฟังก์ชั่นดังกล่าว?
theMayer

0 รายการโดยเฉลี่ยแล้วจะคืน NaN หรือโยนข้อยกเว้นหารด้วยศูนย์เพียงเพราะวิธีการกำหนดฟังก์ชั่น ไฟล์ที่มีชื่อที่ไม่สามารถมีอยู่อาจไม่มีอยู่หรือจะทริกเกอร์ข้อผิดพลาดแล้ว ไม่มีเหตุผลที่น่าสนใจในการจัดการกรณีเหล่านี้เป็นพิเศษ
cHao

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

-3

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


มันผิดอย่างยิ่งสำหรับนักออกแบบที่จะคิดว่าคอลเลกชันจะถูกส่งผ่านเสมอและตรงไปที่ซ้ำมากกว่าคอลเลกชันดังกล่าวจะต้องตรวจสอบเพื่อให้แน่ใจว่าอาร์กิวเมนต์ที่ได้รับเป็นไปตามประเภทข้อมูลที่คาดไว้ ...
Clement Mark-Aaba

3
"ประเภทอินพุตที่หลากหลาย" ดูไม่เกี่ยวข้องที่นี่ คำถามถูกติดแท็กc #ซึ่งเป็นภาษาที่พิมพ์ได้ดี นั่นคือคอมไพเลอร์รับประกันว่าอินพุตเป็นของสะสม
gnat

กรุณา google "กฎของหัวแม่มือ" คำตอบของฉันเป็นความระมัดระวังทั่วไปว่าเป็นโปรแกรมเมอร์ที่คุณทำข้อโต้แย้งฟังก์ชั่นห้องพักสำหรับเหตุการณ์ที่ไม่คาดฝันหรือผิดพลาดหนึ่งของเหล่านี้สามารถส่งผ่านไปอย่างไม่ถูกต้อง ...
ผ่อนผันมาร์ค Aaba

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