จะหลีกเลี่ยงชื่อทั่วไปสำหรับคลาสนามธรรมได้อย่างไร?


10

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

  • ดีกว่าที่จะรักษาคลาสที่ได้รับในฐานะลูกค้าและตั้งชื่อคลาสพื้นฐานตามส่วนของฟังก์ชันที่ใช้? ให้ความหมายมากกว่านี้ แต่จะละเมิด is-a เช่น EmailAcquirer จะเป็นชื่อที่สมเหตุสมผลเนื่องจากได้มาสำหรับคลาสที่ได้รับมา แต่คลาสที่ได้รับจะไม่ได้รับสำหรับใคร
  • หรือชื่อที่คลุมเครือจริงๆเพราะใครจะรู้ว่าคลาสที่ได้รับมาจะทำอะไร อย่างไรก็ตาม "ตัวประมวลผล" ยังคงกว้างเกินไปเนื่องจากมันเป็นการทำงานที่เกี่ยวข้องมากมายเช่นการเข้าสู่ระบบและการใช้ IMAP

มีทางออกจากภาวะที่กลืนไม่เข้าคายไม่ออกนี้ไหม?

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


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

3
@ Steve314 - ใช่ Steve McConnell, Code Complete, 1st ed., บทที่ 4 หรือ 5 บนกิจวัตร การอภิปรายอย่างกว้างขวางเกี่ยวกับการตั้งชื่อในบทเหล่านี้โดยสรุปถ้าคุณไม่มีชื่อที่ดีคุณอาจไม่มีฟังก์ชั่นที่ดี
djechlin

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

1
@ Steve314 การเขียนโปรแกรมนั้นเกี่ยวกับการจัดการความซับซ้อนและหากสมองของคุณไม่สามารถหาคำสำหรับบางสิ่งบางอย่างมีโอกาสที่ดีมากมันจะไม่สามารถจัดการความซับซ้อนของมันเมื่อมันต้องทำสิ่งต่าง ๆ เช่นใช้มันใน ประโยคที่ใหญ่ขึ้นหรือเป็นส่วนหนึ่งของระบบที่ใหญ่กว่า จริงๆแล้วมันไม่ใช่การเรียกร้องอย่างกล้าหาญที่จะบอกว่าไม่สามารถหาชื่อที่ดีได้ซึ่งเป็นสาเหตุใหญ่ที่ทำให้หยุดกังวล แต่สิ่งนี้ถูกกล่าวถึงอย่างกว้างขวางใน McConnell ฉันขอแนะนำให้อ่านบททั้งสองอย่างน้อยที่สุดแม้ว่าหนังสือทั้งเล่มจะคุ้มค่าที่จะอ่านปก - ต่อ - ปก
djechlin

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

คำตอบ:


10

ปัญหาไม่ใช่ชื่อ แต่คุณใส่มากเกินไปในชั้นเดียว

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

ดีกว่าที่จะทำสิ่งนี้กับคลาสที่แยกต่างหากมากกว่ากับการสืบทอด

ฉันแนะนำ:

  • MessageIterator ที่เป็นนามธรรมคลาสย่อยโดย POPMailBoxDownloader

  • คลาสอื่นที่เป็นเจ้าของ POPMailBoxDownloader และทำบางสิ่งบางอย่างกับข้อความ


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

6

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

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

ฉันไม่เห็นปัญหาเมื่อใช้ชื่อทั่วไปเช่น "ตัวประมวลผล" ถ้ามันสะท้อนถึงวัตถุประสงค์ทั่วไปของคลาสนามธรรม

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


2

เพื่อถอดความแฟรงค์แชปมันเป็นสิ่งที่มันเป็นและควรจะตั้งชื่ออย่างนั้น ตัวอย่างของคุณไม่ขุดลึกลงไปในการประมวลผลที่เกิดขึ้น มันคือEmailToTroubleTicketProcessorการEmailGrammarCorrectorหรือEmailSpamDetector?

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

นั่นไม่จริงอย่างแน่นอน คำถามที่คุณไม่สามารถตอบสำหรับสิ่งที่เป็นนามธรรมคือ " วิธีการที่ไม่ได้ทำสิ่งที่มันไม่?" เพราะนั่นคือการใช้งานเฉพาะ หากEmailSenderชั้นเรียนมีDeliveryStatus deliver(Email e)วิธีการมีสัญญาโดยนัยว่าการดำเนินการจะใช้อีเมลพยายามส่งมันและส่งคืนสถานะบางอย่างเกี่ยวกับวิธีการใช้งาน คุณไม่สนใจว่าจะเชื่อมต่อกับเซิร์ฟเวอร์ SMTP หรือพิมพ์ออกมาเพื่อมัดติดกับนกพิราบตัวผู้ตราบใดที่การใช้งานทำตามที่สัญญาไว้ บทคัดย่อเพียงปริมาณที่สัญญาเพื่อให้การดำเนินการสามารถพูดว่า "ใช่ฉันทำอย่างนั้น"


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

มันยังคงเป็นสิ่งเดียวกัน แม้ว่าวิธีการของคุณเป็นvoid doWhatYouDoWith(Email e)อย่างไรคุณก็ยังสามารถเรียกชั้นเรียนได้EmailDisposerซึ่งเฉพาะเจาะจงมากพอที่จะพูดในสิ่งที่ทำได้ แต่กว้างพอที่จะนำไปปฏิบัติได้อย่างไร แม้ว่าฉันคิดว่า @KrisVanBael จับมัน: หากคุณหันไปใช้สิ่งที่คลุมเครืออาจมีมากเกินไปภายใต้หลังคาเดียวกัน
Blrfl

0

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


"EmailBaseClass" จะเหมือนกับการตั้งชื่อint age"ageInteger" เท่านั้นยิ่งแย่ลงเพราะฉันคาดว่าจะได้รับอีเมลข้อความธรรมดาอีเมล MIME และอื่น ๆ จากมัน ไม่จำเป็นต้องอธิบายสิ่งที่นำหน้าด้วยคำนั้นabstractในตอนแรก (นี่คือ Java) คุณมีความเข้าใจที่เฉพาะเจาะจงสำหรับส่วนฐานของชั้นนี้หรือไม่? และความเข้าใจที่ลึกซึ้งยิ่งขึ้นก็ยังไม่สามารถแก้ปัญหาการตั้งชื่อสิ่งที่กำลังจะข้ามความสัมพันธ์ฉันสามารถมีบางสิ่งที่คลุมเครือหรือกว้างเกินไปฉันไม่เห็นทางออกจากเรื่องนี้เว้นแต่ว่าฉันมี ความเข้าใจที่ลึกซึ้งยิ่งขึ้นเกี่ยวกับการมีความเข้าใจที่ลึกซึ้งยิ่งขึ้น
djechlin

@djechlin - มีกรณีที่หายากที่ไหนageIntegerหรือสิ่งที่ชอบมันเหมาะสมจริง สัญกรณ์ฮังการีเป็นเวอร์ชันย่อจากบริบทที่เกิดขึ้นมากมาย แน่นอนมีบางครั้งที่คุณอาจต้องการบางสิ่งบางอย่างตามแนวของageNumericและageStringในขอบเขตเดียวกันโดยมีการระบุประเภทในชื่อที่เป็นวิธีที่ง่ายที่สุดและชัดเจนที่สุดที่จะแก้ความกำกวม
Steve314

@djechlin ฉันพบว่าเป็นการง่ายที่สุดในการทำงานกับโค้ดซึ่งฉันสามารถดูเพื่อทำความเข้าใจได้ นั่นคือชื่อบอกฉันว่าฉันทำงานกับอะไร ไม่จำเป็นต้องรู้ว่าsystemControllerเป็นคลาสฐานนามธรรมหรือใบไม้ในลำดับชั้นขนาดใหญ่ หลักสูตรนี้อาจจะแก้กับ IDE (ตามที่ผมคิดว่าเป็นกรณีที่มีการพัฒนา Java มากที่สุด?) ซึ่งทันทีสามารถแจ้งให้ผู้ใช้เกี่ยวกับเนื้อหาและโครงสร้างของชั้นเรียนเพื่อให้จริงลึกซึ้งชื่อไม่เป็นธรรมในทำนองเดียวกัน
zxcdw
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.