รักษาคลาสและวิธีการของฉันให้เล็กที่สุดเท่าที่จะทำได้?


20

ไม่กี่วันที่ผ่านมาฉันได้พูดคุยกับผู้สมัครระดับปริญญาเอกด้านวิศวกรรมซอฟต์แวร์และในบางครั้งเธอพูดกับฉัน:

รักษาชั้นเรียนและวิธีการของคุณให้เล็กที่สุด

และฉันสงสัยว่านี่เป็นวิธีปฏิบัติที่ดีเสมอ

ฉันหมายถึงตัวอย่างมันคุ้มค่าที่จะมีชั้นเรียนที่มีเพียง 2 attibutes ในนั้น? ตัวอย่างเช่นในบางวิธีฉันต้องการคู่จำนวนเต็มเพื่อทำงานกับ ฉันควรเขียนคลาส "PairOfIntgers" หรือไม่

วิธีคิดแบบนี้ "แตก" โค้ดเป็นจำนวนมากเกินไปหรือไม่


10
ควรจะเป็น"As small as possible, but no smaller."
StuperUser

"ฉันหมายถึงตัวอย่างมันคุ้มค่าที่จะมีชั้นเรียนที่มีเพียง 2 attibutes ในนั้น" - สามารถค้นหาคำว่า "Primitive Obsession" (เช่นjamesshore.com/Blog/PrimitiveObsession.html )
Torsten

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

คำตอบ:


23

คำแนะนำนั้นมีเมล็ดพืชจริง แต่ IMHO มันไม่ได้แสดงออกมาอย่างดีดังนั้นจึงง่ายที่จะเข้าใจผิดและ / หรือนำไปสู่การโง่สุดขีด ไม่ว่าในกรณีใดก็ตามนี่ควรเป็นกฎง่ายๆ และคุณควรบอกเป็นนัยในกฏเช่นว่า"อยู่ในขอบเขตที่สมเหตุสมผล"หรือ"แต่อย่าลืมใช้สามัญสำนึกของคุณ" :-)

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


1
แน่นอนว่ากฎที่จะไม่ติดตามคนตาบอดชั้นเรียนขนาดเล็กมากเกินไปนั้นแย่กว่าชั้นเรียนขนาดใหญ่เพียงไม่กี่แห่งส่วนใหญ่
Ryathal

4
กฎง่ายๆของฉันคือถ้าคุณไม่เห็นวิธีการใช้งานบนหน้าจอทั้งหมดในครั้งเดียวให้ทำการรีแฟคเตอร์
Dan Ray

6
@DanRay ใช่ฉันเคยมีกฎเดียวกันจนผมอ่านรหัสที่สะอาด มันค่อนข้างน่าตกใจ แต่ก็ค่อย ๆ ทำให้ฉันเหมาะสมที่สุดที่จะลงไปประมาณ 10 บรรทัด
PéterTörök

2
IMO Clean Codeเป็นสิ่งที่น่ากลัวอย่างยิ่งต่อวิธีการเล็ก ๆ ปัญหาคือว่าเมื่อวิธีการที่มีขนาดเล็กลงจะมีมากขึ้นของพวกเขา แน่นอนว่าวิธีการที่ยาวเกินไปนั้นยาวเกินไป แต่ Bob Martin ดูเหมือนจะชอบวิธีการ 10 1-line มากกว่า 1 10-line หนึ่ง บางทีมันอาจจะเป็นเคล็ดลับทางการศึกษาบางอย่างฉันไม่อยากจะเชื่อว่ามีคนคิดว่ารหัสในหนังสือเล่มนั้นดี
Joonas Pulakka

5
@ JoonasPulakka - สมมุติว่าฉันไม่เคยอ่านวิธีและคิดว่า "ฉันหวังว่าวิธีนี้จะทำได้มากกว่านี้" โดยการย่อให้เล็กลงคุณสามารถเขียนชื่อวิธีการบรรยายที่มักไม่จำเป็นต้องอ่านเนื้อหาของเมธอดทั้งหมด ฉันพบว่าคำแนะนำในClean Codeนั้นสมเหตุสมผลดี เราจะต้องเห็นด้วยไม่เห็นด้วย :)
David Harkness

9

ปัญหาที่สำคัญต่อความเครียดที่นี่คือการสร้างแนวคิดที่ดี ชั้นเรียนขนาดเล็กที่มีคู่อย่างอิสระและมีการทำงานร่วมกันสูงเป็นผลิตภัณฑ์ของแนวคิดที่ดี

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

ข้อดีอีกข้อหนึ่งในการสร้างคลาสในกรณีนี้คือคลาสสามารถพัฒนาได้ดีกว่า / ดีกว่าสมมติว่าโครงสร้างข้อมูลระดับล่างเช่น Map หรือ List สามารถ

ประการที่สามสิ่งที่เป็นนามธรรมที่ดีสามารถปรับปรุงความสามารถในการอ่านได้อย่างมาก คลาสที่เป็นไปตาม SRP มักจะเข้าใจได้ง่ายกว่ามนุษย์มากกว่าคลาสที่ไม่มี

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


2

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


2

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

พยายามทำให้ชั้นเรียนเล็ก ๆ และวิธีการก็ยิ่งเล็กลง อาจจะ 10 เส้น?! ขณะนี้ฉันกำลังพยายามใช้การออกแบบการไหลและส่วนประกอบที่ใช้เหตุการณ์ซึ่งดูเหมือนจะช่วยให้ชั้นเรียนมีขนาดเล็ก ครั้งแรกฉันกังวลที่จะไปหลายชั้น แต่ใช้งานได้จริง !!! http://geekswithblogs.net/theArchitectsNapkin/archive/2011/03/19/flow-design-cheat-sheet-ndash-part-i-notation.aspx http://geekswithblogs.net/theArchitectsNapkin/archive/2011/03 /20/flow-design-cheat-sheet-ndash-part-ii-translation.aspx


2

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

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


0

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

เมื่อฉันดูรหัสของฉันฉันรู้ว่าวิธีการมีขนาดใหญ่เกินไป หากทำมากเกินไปและอ่านยากเกินไปแสดงว่าถึงเวลาปรับเปลี่ยน

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

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


อย่าทำให้วิธีการเล็กลงแทนที่จะทำตาม SRP และมันจะทำงานโดยอัตโนมัติ
Vinay Prajapati

0

ลุงบ๊อบบอกว่าคุณควร refactor / แยก / สารสกัดจากวิธีการของคุณจนกว่ามันจะเป็นไปไม่ได้ที่จะทำให้พวกเขามีขนาดเล็กลง เรื่องนี้มักจะจบลงด้วยการมีหลายวิธีด้วยกัน 3 หรือ 4 บรรทัด เมื่อคุณได้รับวิธีการมากเกินไปคุณต้องทำคลาสเพิ่มเติม

หากคุณพยายามติดตาม SRP และ Abstraction ต่อระดับหนึ่งวิธีกฎเหล่านี้ให้บริการคุณได้ดี อย่างน้อยพวกเขาก็ให้บริการฉันดี การเล็งให้ "เล็กที่สุด" ให้วิธีการเล็ก ๆ ที่สมเหตุสมผลแก่ฉันเพราะฉันมักจะขาดเป้าหมาย

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

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