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


9

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

หากมีปัญหาแล้วภายใต้สถานการณ์ใดที่เหมาะสมที่จะทำเช่นนั้น

คำตอบของคำถามนี้เปลี่ยนไปอย่างไรขึ้นอยู่กับว่าภาษานั้นเป็นแบบไดนามิกหรือไม่?

แก้ไข:นี่คือการชี้แจงว่าคีย์จะคงที่และเป็นส่วนหนึ่งของรหัสไม่ใช่ข้อมูล สิ่งที่เรามักจะสร้างชั้นเรียน คำถามคือทำไมการใช้ hashtable ไม่ถูกต้องหากสร้างคลาสจริง ๆ แล้วเป็นตัวเลือกที่ถูกต้อง

คำตอบ:


11

ใช้คลาสที่กำหนดไว้ดีกว่าเป็นประเภทส่งคืนกว่า hashtable ซึ่งเก็บค่าโดยพลการเป็นคู่ชื่อ / ค่า

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

  2. วิธีการเป็นสัญญาระหว่างผู้โทรและบริการ สิ่งที่สำคัญที่สุดในวิธีการหนึ่งคืออินพุตและเอาต์พุต อินพุตและเอาต์พุตนี้ควรอ่านและเข้าใจได้ง่ายและจัดทำเอกสารด้วยตนเอง ถ้าคุณใช้คลาส Person เป็นค่าส่งคืนซึ่งมีชื่อนามสกุลอายุ - มันเป็นเอกสารด้วยตนเอง หากคุณสร้าง Javadoc สำหรับสิ่งนี้ผู้ใช้สามารถนำทางระหว่างคลาสเพื่อทำความเข้าใจกับสิ่งที่ดีกว่านี้ หากคุณใช้ hashtable คุณต้องอธิบายในความคิดเห็นซึ่งจะไม่มีใครอ่านหรืออัปเดตเมื่อสิ่งต่าง ๆ เปลี่ยนไป

  3. คุณไม่สามารถใช้ข้อมูลทั่วไปเช่นHashMap<String,String>ในกรณีที่คุณต้องการเพิ่มตัวเลข (อายุพูด) ในคำสั่งส่งคืน หากคุณไม่ใช้ยาชื่อสามัญคุณจะต้องทำการโยนกลับไปกลับมาระหว่างวัตถุกับชนิดที่แท้จริง คุณสามารถบันทึกสิ่งนี้หากคุณใช้การพิมพ์แบบไดนามิก

  4. นอกจากนี้ยังมีโอกาสเกิดความล้มเหลวของรันไทม์มากกว่าการจับปัญหาในเวลารวบรวม เช่นถ้ามีคนลบรายการออกจาก hashmap และหนึ่งในผู้โทรเก่าคาดว่าจะมีรายการลูกค้าล้มเหลวในระหว่างรันไทม์ มันจะดีกว่าเสมอที่จะจับปัญหานี้ในเวลารวบรวม

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

มันจะเป็นการดึงดูดให้ใช้ hashmap เป็นชนิดส่งคืนเนื่องจากคุณสามารถหลีกเลี่ยงการสร้างคลาสสองสามต้น แต่จะเป็นฝันร้ายในการรักษารหัสในอนาคต มุ่งเน้นวัตถุไป !!!!


1
คุณดูเหมือนจะเข้าใจคำถามได้อย่างถูกต้อง ขอบคุณ
มูฮัมหมัดฮะซันข่าน

8

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

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

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

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

แก้ไข - คะแนนส่วนใหญ่ในคำตอบนี้หยุดใช้เมื่อคุณพูดถึงภาษาแบบไดนามิก :)


เกิดอะไรขึ้นถ้าภาษาเป็นแบบไดนามิก
มูฮัมหมัดฮะซันข่าน

ฉันไม่ใช่ผู้เชี่ยวชาญในภาษาไดนามิกดังนั้นคนอื่นอาจให้คำตอบที่ดีกว่า แต่ฉันรู้ว่าภาษาแบบไดนามิกไม่ได้รวบรวมการตรวจสอบประเภทเวลา แต่ในกรณีนั้นการส่งคืนวัตถุและการส่งคืนตารางแฮชไม่ได้แตกต่างกันมาก ..
MattDavey

3
@Hasan Khan: ในกรณีนี้อาจไม่มีความแตกต่างระหว่าง hashtable และอินสแตนซ์ของคลาส ตัวอย่างเช่นใน Javascript วัตถุทั้งหมดเป็นแฮชเทเบิ้ลและ object.property นั้นเหมือนกับวัตถุ ['property']
Michael Borgwardt

“ ด้วยตารางแฮชคุณอาจต้องทำการค้นหา / แทนที่ในไฟล์ต้นฉบับทั้งหมดซึ่งอาจเป็นปัญหา” เฉพาะในกรณีที่คุณได้เลือกกุญแจที่ไม่ดีและไม่เคยพยายามที่จะแยกตัวเลือกมาตรฐานออกมาเพื่อให้มันถูกกำหนดไว้ในที่เดียว…
Donal Fellows

7

ข้อโต้แย้งที่สำคัญที่สุดในกรณีนี้คือคุณกำลังเปิดเผยข้อมูลแก่ผู้บริโภคมากเกินไป รหัสการบริโภคจำเป็นต้องรู้ว่ามันคือการรวบรวมคีย์ - ค่า (พจนานุกรม) ของการเรียงลำดับบางอย่าง ไม่ว่าจะนำมาใช้เป็น hashmap, รายการความสัมพันธ์, trie หรืออะไรก็ตามที่ค่อนข้างไม่น่าสนใจ ดังนั้นวิธีที่เหมาะสมคือการกลับมาโดยอินเทอร์เฟซที่เหมาะสม ( IDictionaryหรือภาษาที่คุณเลือกใช้) แทนที่จะเป็นตามประเภทที่แท้จริง

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

แก้ไข :

เพื่อความชัดเจนฉันใช้คำศัพท์เพื่อหมายถึงโครงสร้างข้อมูลคีย์ - ค่าทั่วไปชนิดที่นี่ ผมไม่ได้หมายถึงการดำเนินงานเฉพาะภาษาใด ๆ เช่นงูใหญ่dictหรือ Dictionary.NET


1
+1 สำหรับ "มันขึ้นอยู่กับว่าคุณคิดว่าตัวเองเป็นส่วนหนึ่งของข้อมูลหรือเป็นส่วนหนึ่งของรหัส" - นั่นเป็นวิธีที่ดีในการวาง ไม่แน่ใจว่าคำว่า 'พจนานุกรม' มีความเป็นสากลมากเพียงใดเมื่อเทียบกับ 'แผนที่' เช่น
MattDavey

การส่งคืนพจนานุกรมไม่ได้มีเจตนา กุญแจเป็นส่วนหนึ่งของรหัสไม่ใช่ข้อมูล
มูฮัมหมัดฮะซันข่าน

คำถามจริงคือเหตุผลที่อยู่เบื้องหลัง 'คุณควรสร้างประเภทที่เหมาะสม' คำถามคือทำไม
มูฮัมหมัดฮะซันข่าน

2

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


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

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