แนวทางที่ดีที่สุดในการตั้งชื่อชั้นเรียนคืออะไร?


92

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

คลาสที่ใช้รูปแบบการออกแบบเฉพาะอาจได้รับชื่อตามชื่อรูปแบบที่รู้จักกันดี (เช่น FooFactory, FooFacade) และคลาสที่จำลองแนวคิดโดเมนโดยตรงสามารถใช้ชื่อของพวกเขาจากโดเมนปัญหาได้ แต่คลาสอื่น ๆ ล่ะ มีอะไรที่เหมือนกับอรรถาภิธานโปรแกรมเมอร์ที่ฉันสามารถหันไปใช้เมื่อฉันขาดแรงบันดาลใจและต้องการหลีกเลี่ยงการใช้ชื่อคลาสทั่วไป (เช่น FooHandler, FooProcessor, FooUtils และ FooManager)


6
นี่เป็นคำถามที่ยอดเยี่ยม! การปิดมันเป็นสิ่งที่ไม่ยุติธรรมของ IMHO ดีกว่าที่จะย้ายไซต์โปรแกรมเมอร์
Timofey

1
ฉันเห็นด้วยควรเปิดใหม่หรือย้าย
ftl


ฉันเคยเห็นคำถามดีๆมากมายเหล่านี้ "ปิดโดย casperOne" บางทีเขาอาจทำหน้าที่เป็นผู้ลบที่วิกิพีเดีย?
Perlator

คำตอบ:


59

ฉันจะอ้างอิงข้อความบางส่วนจากรูปแบบการใช้งานโดย Kent Beck:

ชื่อ Superclass แบบง่าย

"[... ] ชื่อควรสั้นและเจาะลึกอย่างไรก็ตามในการทำให้ชื่อแม่นยำบางครั้งดูเหมือนจะต้องใช้คำหลายคำทางออกจากภาวะที่กลืนไม่เข้าคายไม่ออกนี้คือการเลือกคำอุปมาที่ชัดเจนสำหรับการคำนวณโดยมีอุปมาอุปไมยในใจแม้กระทั่ง คำเดียวทำให้เกิดการเชื่อมโยงการเชื่อมต่อและความหมายที่หลากหลายตัวอย่างเช่นในเฟรมเวิร์กการวาดภาพ HotDraw ชื่อแรกของฉันสำหรับวัตถุในรูปวาดคือ DrawingObject Ward Cunningham มาพร้อมกับอุปมาอุปมัยการพิมพ์: ภาพวาดก็เหมือน หน้าจัดวางที่พิมพ์ออกมารายการกราฟิกในหน้าเป็นตัวเลขดังนั้นคลาสจึงกลายเป็นรูปในบริบทของการเปรียบเทียบFigure จะสั้นกว่าสมบูรณ์กว่าและแม่นยำกว่าDrawingObject ในเวลาเดียวกัน "

ชื่อคลาสย่อยที่ผ่านการรับรอง

"ชื่อของคลาสย่อยมีสองงานพวกเขาจำเป็นต้องสื่อสารว่าคลาสนั้นเป็นอย่างไรและแตกต่างกันอย่างไร [... ] ไม่เหมือนกับชื่อที่อยู่ที่รากของลำดับชั้นชื่อคลาสย่อยจะไม่ได้ใช้บ่อยเท่าในการสนทนา เพื่อให้สามารถแสดงออกได้ในราคาที่รัดกุม [... ]

กำหนดคลาสย่อยที่ทำหน้าที่เป็นรากของลำดับชั้นชื่อง่ายๆของตนเอง ตัวอย่างเช่นHotDrawมีHandleคลาสซึ่งนำเสนอการแก้ไขตัวเลขเมื่อเลือกรูป มันถูกเรียกว่าเพียงแค่จับ ทั้งๆที่มีการขยายรูป มีทั้งครอบครัวของจับและพวกเขาเหมาะสมที่สุดมีชื่อเช่น StretchyHandleและTransparencyHandle เนื่องจากHandleเป็นรากของลำดับชั้นของตัวมันเองจึงสมควรได้รับชื่อ superclass ที่เรียบง่ายมากกว่าชื่อคลาสย่อยที่ผ่านการรับรอง

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

อินเตอร์เฟซ

อินเทอร์เฟซการตั้งชื่อสองรูปแบบขึ้นอยู่กับว่าคุณคิดอย่างไรกับอินเทอร์เฟซ ควรตั้งชื่ออินเทอร์เฟซเป็นคลาสที่ไม่มีการนำไปใช้ราวกับว่าเป็นคลาส ( Simple Superclass Name , Qualified Subclass Name ) ปัญหาอย่างหนึ่งของการตั้งชื่อสไตล์นี้คือชื่อที่ดีจะถูกใช้หมดก่อนที่คุณจะเข้าสู่คลาสการตั้งชื่อ อินเทอร์เฟซที่เรียกว่าFileต้องการคลาสการใช้งานที่เรียกว่า ActualFile , ConcreteFileหรือ (yuck!) FileImpl(ทั้งคำต่อท้ายและตัวย่อ) โดยทั่วไปการสื่อสารว่าใครกำลังจัดการกับวัตถุที่เป็นรูปธรรมหรือนามธรรมเป็นสิ่งสำคัญไม่ว่าจะนำวัตถุนามธรรมมาใช้เป็นอินเทอร์เฟซหรือซูเปอร์คลาสมีความสำคัญน้อยกว่า การชะลอความแตกต่างระหว่างอินเทอร์เฟซและซูเปอร์คลาสเป็นสิ่งที่ดี> รองรับโดยรูปแบบการตั้งชื่อนี้ทำให้คุณมีอิสระที่จะเปลี่ยนใจในภายหลังหากจำเป็น

บางครั้งการตั้งชื่อคลาสที่เป็นรูปธรรมก็มีความสำคัญต่อการสื่อสารมากกว่าการซ่อนการใช้อินเทอร์เฟซ ในกรณีนี้ให้นำหน้าชื่ออินเทอร์เฟซด้วย“ I” ถ้าอินเตอร์เฟซที่เรียกว่าiFileชั้นสามารถเรียกได้ว่าเพียงแค่ไฟล์

สำหรับรายละเอียดเพิ่มเติมซื้อหนังสือเล่มนี้! มันคุ้มค่า! :)


1
"บางครั้งการตั้งชื่อคลาสที่เป็นรูปธรรมก็มีความสำคัญต่อการสื่อสารมากกว่าการซ่อนการใช้อินเทอร์เฟซในกรณีนี้ให้นำหน้าชื่ออินเทอร์เฟซด้วย" I "ถ้าอินเทอร์เฟซเรียกว่า IFile คลาสสามารถเรียกง่ายๆว่า File" มันตลกมากเพราะในหนังสือ Clean Code โดย Robert C. Martin ฉันพบว่าเราอยากจะตั้งชื่อการใช้งานเป็น FileImpl แทนที่จะตั้งชื่ออินเทอร์เฟซเช่น IFile เพราะเราไม่ต้องการให้ลูกค้ารู้ว่าเรากำลังให้บริการ อินเตอร์เฟซ. และในหนังสือ ^ มีคำพูดจากหนังสือที่คุณอ้างถึง :)
Cristian Ciobotea

39

ไปที่ MyClassA, MyClassB เสมอ - ช่วยให้สามารถจัดเรียงอัลฟ่าที่ดีได้ ..

ฉันล้อเล่น!

นี่เป็นคำถามที่ดีและเป็นสิ่งที่ฉันประสบเมื่อไม่นานมานี้ ฉันกำลังจัดระเบียบโค้ดเบสใหม่ในที่ทำงานและมีปัญหาว่าจะวางอะไรและจะเรียกว่าอะไร ..

จริงปัญหา?

ฉันมีชั้นเรียนที่ทำมากเกินไป หากคุณพยายามยึดมั่นในหลักการความรับผิดชอบเดียวมันจะทำให้ทุกอย่างมารวมกันได้ดีกว่ามาก .. แทนที่จะเป็นคลาสPrintHandlerเสาหินเดียวคุณสามารถแยกย่อยออกเป็นPageHandler , PageFormatter (และอื่น ๆ ) จากนั้นมีคลาสเครื่องพิมพ์หลักซึ่ง รวบรวมทั้งหมดเข้าด้วยกัน

ในการ re-org ของฉันฉันใช้เวลาพอสมควร แต่สุดท้ายฉันก็ทิ้งโค้ดที่ซ้ำกันจำนวนมากทำให้ codebase ของฉันมีเหตุผลมากขึ้นและได้เรียนรู้อะไรมากมายเมื่อต้องคิดก่อนที่จะโยนวิธีพิเศษในชั้นเรียน: D

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

โชคดี!


เห็นด้วยกับการไม่ใส่ชื่อรูปแบบลงในชื่อคลาส จะเกิดอะไรขึ้นหากรูปแบบเปลี่ยนแปลงในภายหลังเมื่อการใช้งานเปลี่ยนไป
thegreendroid

2
ฉันควรใส่ชื่อของรูปแบบในชื่อ ทำไม? เพราะถ้าฉันต้องดูรายละเอียดการใช้งาน (เช่นตัวสร้างส่วนตัว) เพื่อที่จะพบว่ามันเป็นซิงเกิลตันนั่นทำให้ฉันช้าลงในฐานะผู้อ่านและขึ้นอยู่กับระดับทักษะของฉันฉันอาจไม่เข้าใจว่ามันเป็นส่วนของคลาสจริงๆ ของรูปแบบทั่วไป Singleton และ private constructor เป็นตัวอย่างที่น่าสงสัย แต่สำหรับรูปแบบที่ซับซ้อนมากขึ้น (Visitor, Adapter เป็นต้น) มันค่อนข้างซับซ้อน ถ้ารูปแบบเปลี่ยนไป Chaces คือคลาสเหล่านั้นจะไม่มีอยู่อีกต่อไป ...
dragan.stepanovic

28

คำพูดที่ยอดเยี่ยมของ Josh Bloch เกี่ยวกับการออกแบบ API ที่ดีมีคำแนะนำที่ดีเล็กน้อย:

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

หากปัญหาของคุณคือการตั้งชื่อคลาสภายในที่เปิดเผยบางทีคุณควรรวมคลาสเหล่านั้นไว้ในคลาสที่ใหญ่ขึ้น

หากปัญหาของคุณคือการตั้งชื่อคลาสที่มีการใช้งานหลายอย่างคุณควรพิจารณาแยกเป็นหลายคลาส

หากนั่นเป็นคำแนะนำที่ดีสำหรับ API สาธารณะก็จะไม่ส่งผลเสียต่อคลาสอื่น ๆ


1
ลิงค์วิดีโอบน youtube youtube.com/watch?v=aAb7hSCtvGw
Andrew Harry

13

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

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


9

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


3

หาก "FooProcessor" ของคุณทำกระบวนการ foos จริงๆก็อย่าลังเลที่จะตั้งชื่อนั้นเพียงเพราะว่าคุณมี BarProcessor, BazProcessor ฯลฯ อยู่แล้วหากมีข้อสงสัยให้ชัดเจนดีที่สุด นักพัฒนาคนอื่น ๆ ที่ต้องอ่านโค้ดของคุณอาจไม่ได้ใช้อรรถาภิธานเดียวกันกับคุณ

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

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

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