เมื่อใดที่ฉันควรใช้คลาส 2 คุณสมบัติเหนือโครงสร้างที่สร้างไว้ล่วงหน้าเช่น KeyValuePair


31

เมื่อใดที่คุณควรใส่ข้อมูล Key / Value ในคลาสของตัวเองแทนที่จะใช้โครงสร้างทั่วไปที่สร้างไว้ล่วงหน้าเช่น a KeyValuePairหรือ a Tuple?

ตัวอย่างเช่น ComboBox ส่วนใหญ่ที่ฉันสร้างมี DisplayName และค่า นี่เป็นข้อมูลประเภทหนึ่งที่ฉันพยายามจะตัดสินใจว่าจะใส่คลาสใหม่เมื่อใดและเมื่อใดควรใช้ KeyValuePair

ขณะนี้ฉันกำลังทำงานกับบางสิ่งที่ใช้iCalendarงานอยู่และในที่สุดข้อมูลของผู้ใช้ที่เลือกจะได้รับการรวมกันเป็นkey1=value1;key2=value2;สตริงชนิดหนึ่ง ฉันเริ่มต้นด้วยการใส่ข้อมูลในKeyValuePair<string,string>แต่ตอนนี้ฉันสงสัยว่ามันควรจะเป็นชั้นเรียนของตัวเองแทน

โดยรวมแล้วฉันสนใจที่จะทราบว่าจะใช้แนวทางใดเมื่อตัดสินใจใช้โครงสร้าง / คลาสที่มีอยู่เช่นKeyValuePairวัตถุ 2 คุณสมบัติและในสถานการณ์แบบใดที่คุณจะใช้อีกแบบหนึ่ง


3
ภาษาอะไร? ใน Python เราไม่มีภาวะที่กลืนไม่เข้าคายไม่ออกนี้เพราะเรามีtupleประเภท
S.Lott

3
@ S.Lott -. NET BCL มีสิ่งอันดับตั้งแต่ v 4.0
Oded

1
. NET 4 ยังมีประเภท tuple msdn.microsoft.com/en-us/library/system.tuple.aspx
Dave Nay

1
@Oded ในกรณีนี้ผมกำลังสร้างสิ่งที่มีiCalendarและฉันต้องการวัตถุและBYDAY BYSETPOSพวกเขาจะปรากฏใน ComboBoxes แต่ข้อมูลที่แท้จริงจะถูกรวมเข้ากับสตริงกฎที่เกิดขึ้นซ้ำซึ่งเป็นkey=value;ประเภทของสตริง
Rachel

4
@Rachel: โปรดอัปเดตคำถามให้เฉพาะเจาะจงยิ่งขึ้น ความคิดเห็นจำนวนมากไม่ใช่วิธีที่ดีที่สุดในการอธิบายสิ่งต่าง ๆ
S.Lott

คำตอบ:


26

ฉันมักจะใช้วัตถุแทน KeyValuePair หรือ Tuple ในกรณีส่วนใหญ่ ครั้งแรกเมื่อคุณมาใน 6 เดือนต่อมาเพื่อทำการเปลี่ยนแปลงมันเป็นเรื่องง่ายที่จะเข้าใจว่าเจตนาของคุณคืออะไรก่อนหน้านี้มากกว่าที่จะสงสัยว่าอะไรTuple tคืออะไรและทำไมมันถึงมีค่าตลก ๆ ประการที่สองเมื่อสิ่งต่าง ๆ เติบโตและเปลี่ยนแปลงคุณสามารถให้พฤติกรรมการถ่ายโอนข้อมูลอย่างง่าย ๆ ตามที่ต้องการ ต้องการรูปแบบชื่อสองรูปแบบใช่หรือไม่ ง่ายเพียงเพิ่ม ToString () โอเวอร์โหลดที่เหมาะสม ต้องการใช้อินเทอร์เฟซบางอย่างหรือไม่ ไม่มีปัญหา. ในที่สุดมีค่าใช้จ่ายเกือบเป็นศูนย์เกือบทั้งหมดในการสร้างวัตถุอย่างง่ายโดยเฉพาะอย่างยิ่งกับคุณสมบัติอัตโนมัติและการเติมโค้ดให้สมบูรณ์

โบนัส Protip: หากคุณต้องการป้องกันไม่ให้วัตถุเหล่านี้สร้างมลภาวะในเนมสเปซของคุณการสร้างคลาสส่วนตัวภายในชั้นเรียนเป็นวิธีที่ดีในการเก็บสิ่งต่าง ๆ ไว้ใน wraps และป้องกันการพึ่งพาที่แปลก




7

กฎสำหรับการกำหนดคลาสใหม่นั้นง่าย: สรุปโดย "Occam's Razor"

http://c2.com/cgi/wiki?OccamsRazor

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

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

tupleหรือKeyValuePairเป็นที่ต้องการ

จนกระทั่ง

คุณจำเป็นต้องมีฟังก์ชั่นบางอย่างที่ไม่ได้เป็นส่วนหนึ่งของหรือtuple KeyValuePairจากนั้นคุณต้องกำหนดชั้นเรียนของคุณเอง


3
" ไม่เคยออกแบบสิ่งที่คุณขโมยได้ " เกี่ยวกับวิธีที่ฉันชอบในการใช้ถ้อยคำนี้
เจรจาเดี่ยวสิ้นสุด

1
คุณคิดว่าความหมายเป็น "ฟังก์ชันที่ไม่ได้เป็นส่วนหนึ่งของtupleหรือKeyValuePair"? อย่างน้อย KeyValuePair มีความหมายบางรูปแบบ จำกัด แต่สิ่งอันดับ (และอาจเป็นไปได้ การแนะนำคลาสใหม่ควรให้ความหมายที่ชัดเจนแก่คุณเป็นหลัก
Mal Ross

+1 อย่าปะทั้งเรือด้วยเทปพันสายถ้ามันพอดีกับปลั๊ก
Evan Plaice

4
ฉันคิดว่านี่เป็นการใช้มีดโกนของ Occam ในทางที่ผิด ประการที่สองเป็นสิ่งสำคัญที่จะต้องรู้ว่าข้อมูลใดที่มีอยู่ในตัวแปร -1
Bent

4

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

 public class MyPair : Tuple<string, string>

ฉันชอบสิ่งนี้เพราะMyPairกำหนดว่าค่า Tuple คืออะไรและใช้เพื่ออะไร
IAbstract

2
แต่คุณสมบัติของคุณจะถูกเรียกItem1และItem2! มันไม่ง่ายเลยที่จะกำหนดทั้งคลาส? public class SideStrings { public string Left { get; set; } public string Right { get; set; } }
กำหนดค่า

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

2
@ เข้าสู่ระบบ: แต่ประเด็นคืออะไร? การสร้างคลาสของคุณเองนั้นใช้งานได้น้อยกว่าการเขียนทับ
กำหนดค่า

2
@ ผู้สร้างคุณจะได้รับความเท่าเทียมกันและการเปรียบเทียบสิ่งที่ทำงานได้ดีกว่าวัตถุที่กำหนดเอง แต่ถ้าจำเป็นต้องมีการตั้งค่า tuple เป็นวิธีที่ผิดไปแน่นอน
ลงชื่อ

4

S.Lott เขียน

อย่าแนะนำคลาสใหม่โดยไม่มีเหตุผลที่ดี หรือใช้คลาสที่สร้างไว้ล่วงหน้าให้มากที่สุด คิดค้นให้น้อยที่สุด

คุณไม่สามารถใช้คลาสที่สร้างไว้ล่วงหน้าหากคุณต้องกำหนดความรับผิดชอบเฉพาะให้กับวัตถุที่ไม่ได้กำหนดไว้ในคลาสที่สร้างไว้ล่วงหน้า

ให้ฉันบอกว่าทำไมฉันถึงมีปัญหาร้ายแรงกับเรื่องนี้ ตั้งแต่

KeyValuePair [string, string]

ดูเหมือนว่าจะไม่เป็นไร .... คือ KeyValue [string, KeyValue [string, KeyValuePair [string, string]]] ก็โอเคใช่ไหม ผมไม่ทราบว่าสิ่งที่ S.Lott จะพูดกับนี้ แต่เจ้านายของฉันคิดว่ามันเป็นโอเค

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

ป.ล. ฉันเป็น Ultra_Noob ดังนั้นโปรดบอกฉันว่าฉันผิด


2
ฉันคิดว่าKeyValuePair<string,string>มันดีถ้าสมมติว่าสิ่งที่ใส่เข้าไปนั้นเป็นกุญแจและค่านิยม ที่นี่การนำคลาสที่มีอยู่กลับมาใช้ใหม่ถือเป็นชัยชนะเนื่องจากคุณบันทึกการเขียนโค้ดและเพิ่มความสามารถในการทำงานร่วมกัน OTOH การใช้บางสิ่งที่ซับซ้อนเท่าKeyValuePair<string,KeyValuePair<string,string>>ที่เวลาส่วนใหญ่ซับซ้อนเกินกว่าจะใช้งานได้จริง บางครั้งมันอาจจะถูก - เมื่อคุณไม่ต้องการฟังก์ชั่นเพิ่มเติมเมื่อความหมายชัดเจนและเมื่อมันทำงานได้ดีกับคลาสอื่น ๆ YMMV นี่เป็นเพียงการชั่งน้ำหนักข้อดีและข้อ จำกัด
maaartinus

หากคุณกำลังใช้ C # นี่คือประสิทธิภาพการทำงานของ Tuple VS KeyValuePair สิ่งที่คุณอาจต้องการแบ่งปันกับเจ้านายของคุณ?
Ben

3

เมื่อเราพูดว่าคู่คีย์ / ค่าฉันมักจะคิดว่าตารางแฮชหรืออาร์เรย์เชื่อมโยงหรือเพียงแค่วัตถุKeyValuePair ฉันใช้ทั้งหมดและไม่มีความแตกต่างเมื่อฉันใช้อันไหน

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

นอกเหนือจากนั้นฉันต้องการค้นหาด้วยปุ่มหรือเพื่อดำเนินการกับรายการสไตล์ (อาร์เรย์) เช่นพุชและป๊อป

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


3

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


2

ฉันอาจจะเห็นด้วยกับไวล์ดิ้งที่นี่แต่แล้วฉันก็เป็น noob ในเรื่องแบบนี้เช่นกัน

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

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

ดังนั้นคำถามจริง: คุณแทนข้อมูลหรือคุณกำลังใช้ข้อมูลในกลไกหรือไม่? (และฉันจะไม่แนะนำให้ผสมผสานแนวคิดเหล่านี้เข้าด้วยกัน)

จากประสบการณ์ของฉันไม่มีอะไรเลวร้ายไปกว่าการได้เห็น Tuple [string, string] ที่ถูกส่งเข้าสู่วิธีการและไม่มีวิธีการที่จะรู้ได้ทันทีว่า Item1 และ Item2 ควรจะเป็นอะไร ที่ดีที่สุดที่จะใช้ Tuples ภายในวิธีการหรือเป็นสมาชิกส่วนตัวของชั้นเรียนเท่านั้น

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