นักพัฒนาที่ยอดเยี่ยมรู้ว่าจะ Refactor Rails Code เมื่อใดและอย่างไร

เผยแพร่แล้ว: 2022-03-11

Refactor ขนาดใหญ่ : ทำไมคุณถึงทำอย่างนั้น?

ถ้ายังไม่พังก็ไม่ต้องซ่อม

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

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

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

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

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

บางทีคุณอาจดูจริงจังกับพวกเขาและบอกให้พวกเขาปล่อยไว้และอย่าแตะต้องมัน

เมื่อวางแผนว่าจะปรับโครงสร้างโค้ด Rails ใหม่ คุณอาจต้องใช้แผนภูมิที่ซับซ้อนเพื่อเริ่มต้น

คำถามที่ว่า “ทำไมเราถึงอยากทำอย่างนั้น” เป็นเรื่องธรรมชาติและอาจสำคัญพอๆ กับการทำ...

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

การปรับปรุงประสิทธิภาพ

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

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

การปรับปรุงสถาปัตยกรรม

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

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

มาอัพเดทกันจ้า

บางครั้งรหัสก็เขียนได้ดีในตอนแรก คุณมีความสุขมากกับมัน มีความรวดเร็ว หน่วยความจำมีประสิทธิภาพ บำรุงรักษาได้ และสอดคล้องกับข้อกำหนด เริ่มแรก แต่แล้วการเปลี่ยนแปลงข้อกำหนด เป้าหมายธุรกิจเปลี่ยนไป หรือคุณเรียนรู้สิ่งใหม่เกี่ยวกับผู้ใช้ปลายทางของคุณซึ่งทำให้สมมติฐานเริ่มต้นของคุณเป็นโมฆะ โค้ดยังคงใช้งานได้ดี และคุณยังค่อนข้างพอใจกับมัน แต่มีบางอย่างที่น่าอึดอัดใจเมื่อคุณดูมันในบริบทของผลิตภัณฑ์ขั้นสุดท้าย สิ่งต่าง ๆ ถูกวางไว้บนระบบย่อยที่ไม่ถูกต้องเล็กน้อย หรือคุณสมบัติอยู่ในคลาสที่ไม่ถูกต้อง หรือชื่อบางชื่อก็ไม่สมเหตุสมผลอีกต่อไป ตอนนี้พวกเขากำลังทำหน้าที่ในแง่ของธุรกิจที่มีชื่อแตกต่างไปจากเดิมอย่างสิ้นเชิง อย่างไรก็ตาม ยังคงเป็นเรื่องยากมากที่จะให้เหตุผลกับการปรับโครงสร้าง Rails ขนาดใหญ่ทุกประเภท เนื่องจากงานที่เกี่ยวข้องจะอยู่ในขอบเขตเดียวกันกับตัวอย่างอื่นๆ แต่ประโยชน์ที่จับต้องได้น้อยกว่ามาก คิดดูแล้ว ดูแลรักษาได้ไม่ยาก คุณแค่ต้องจำไว้ว่าบางสิ่งเป็นอย่างอื่น คุณแค่ต้องจำไว้ว่า A หมายถึง B และคุณสมบัติ Y บน A เกี่ยวข้องกับ C จริงๆ

และนี่คือประโยชน์ที่แท้จริง ในสาขาจิตวิทยาประสาทวิทยา มีการทดลองมากมายที่บอกว่าความจำระยะสั้นหรือความจำที่ใช้งานได้ของเราสามารถเก็บองค์ประกอบได้เพียง 7+/-2 อย่าง หนึ่งในนั้นคือการทดลองของสเติร์นเบิร์ก เมื่อเราศึกษาเรื่องใดเรื่องหนึ่ง เราเริ่มต้นด้วยองค์ประกอบพื้นฐาน และในขั้นต้น เมื่อเราคิดถึงแนวคิดระดับสูง เราต้องคิดถึงคำจำกัดความของแนวคิดเหล่านั้น ตัวอย่างเช่น พิจารณาคำศัพท์ง่ายๆ “รหัสผ่าน SHA256 เค็ม” เริ่มแรกเราต้องเก็บคำจำกัดความของหน่วยความจำในการทำงานไว้สำหรับ "salted" และ "SHA256" และอาจเป็นคำจำกัดความของ "hash function" แต่เมื่อเราเข้าใจคำศัพท์อย่างถ่องแท้แล้ว มันใช้สล็อตหน่วยความจำเพียงช่องเดียวเพราะเราเข้าใจอย่างสังหรณ์ใจ นั่นเป็นหนึ่งในเหตุผลที่เราต้องเข้าใจแนวคิดระดับล่างอย่างถ่องแท้เพื่อให้สามารถให้เหตุผลเกี่ยวกับแนวคิดระดับสูงกว่าได้ เช่นเดียวกับข้อกำหนดและคำจำกัดความเฉพาะสำหรับโครงการของเรา แต่ถ้าเราต้องจำการแปลเป็นความหมายที่แท้จริงทุกครั้งที่เราพูดถึงโค้ดของเรา การแปลนั้นก็ใช้ช่องหน่วยความจำการทำงานอันล้ำค่าอีกช่องหนึ่ง มันสร้างภาระทางปัญญาและทำให้การให้เหตุผลผ่านตรรกะในโค้ดของเราทำได้ยากขึ้น ในทางกลับกัน หากการให้เหตุผลยากขึ้น แสดงว่ามีโอกาสมากขึ้นที่เราจะมองข้ามจุดสำคัญและแนะนำจุดบกพร่อง

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

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

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

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

การตระเตรียม

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

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

คุณจะต้องได้รับความช่วยเหลือสำหรับกระบวนการปรับโครงสร้างใหม่ คุณอาจชอบอย่างอื่น แต่ฉันชอบกระดาษเปล่ากับปากกา ฉันเริ่มต้นด้วยการเขียนการเปลี่ยนแปลงเริ่มต้นที่ฉันต้องการจะทำที่ด้านบนซ้ายของกระดาษ จากนั้นฉันก็เริ่มมองหาสถานที่ทั้งหมดที่ได้รับผลกระทบจากการเปลี่ยนแปลง และเขียนไว้ภายใต้การเปลี่ยนแปลงครั้งแรก การใช้วิจารณญาณของคุณเป็นสิ่งสำคัญที่นี่ ท้ายที่สุดแล้ว โน้ตและไดอะแกรมบนกระดาษก็พร้อมให้คุณใช้แล้ว ดังนั้นให้เลือกสไตล์ที่เหมาะกับความทรงจำของคุณมากที่สุด ฉันเขียนโค้ดสั้นๆ ที่มีสัญลักษณ์แสดงหัวข้อย่อยด้านล่าง และลูกศรจำนวนมากที่นำไปสู่บันทึกย่ออื่นๆ ที่ระบุถึงสิ่งที่ขึ้นอยู่กับสิ่งนั้นโดยตรง (ลูกศรเต็ม) หรือโดยอ้อม (ลูกศรประ) ฉันยังใส่คำอธิบายประกอบลูกศรด้วยเครื่องหมายชวเลขเพื่อเป็นการเตือนความจำบางอย่างที่ฉันสังเกตเห็นใน codebase จำไว้ว่าคุณจะกลับมาที่บันทึกย่อเหล่านั้นในอีกไม่กี่วันข้างหน้าในขณะที่คุณทำการเปลี่ยนแปลงที่วางแผนไว้ และมันเป็นเรื่องปกติที่จะใช้การเตือนความจำที่สั้นมากและคลุมเครือ เพื่อให้พวกเขาใช้พื้นที่น้อยลงและจัดวางบนกระดาษได้ง่ายขึ้น . สองสามครั้งที่ฉันทำความสะอาดโต๊ะทำงานเป็นเวลาหลายเดือนหลังจากการปรับโครงสร้าง Rails และพบเอกสารฉบับหนึ่ง มันพูดพล่อยๆ ฉันไม่รู้เลยจริงๆ ว่ากระดาษนั่นหมายถึงอะไร ยกเว้นว่าอาจมีคนบ้าเป็นคนเขียนมันออกมา แต่ฉันรู้ว่ากระดาษแผ่นนั้นขาดไม่ได้ในขณะที่ฉันกำลังแก้ไขปัญหา นอกจากนี้ อย่าคิดว่าคุณจำเป็นต้องเขียนการเปลี่ยนแปลงทุกๆ อย่าง คุณสามารถจัดกลุ่มและติดตามรายละเอียดด้วยวิธีอื่น ตัวอย่างเช่น ในรายงานหลักของคุณ คุณสามารถสังเกตได้ว่าคุณต้อง "เปลี่ยนชื่อรายการทั้งหมดของ Ab เป็น Cd" จากนั้นคุณสามารถติดตามข้อมูลเฉพาะได้หลายวิธี คุณสามารถเขียนมันทั้งหมดลงในกระดาษแยกต่างหาก คุณสามารถวางแผนที่จะทำการค้นหาทั่วโลกสำหรับเหตุการณ์ทั้งหมดที่เกิดขึ้นอีกครั้ง หรือคุณสามารถปล่อยให้ไฟล์ต้นฉบับทั้งหมดที่ต้องการเปิดการเปลี่ยนแปลงในตัวแก้ไขที่คุณเลือก และจดบันทึกไว้เพื่อย้อนกลับไปดูเมื่อคุณทำแผนที่การเปลี่ยนแปลงเสร็จแล้ว

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

การดำเนินการ

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

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

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

ปิดเทอม

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

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

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

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

เมื่อไหร่จะไม่ทำ?

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

ความครอบคลุมในการทดสอบของคุณไม่ดี

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

การปรับโครงสร้างใหม่ไม่ได้ถูกขับเคลื่อนโดยคุณสมบัติใหม่และ codebase ไม่ได้เปลี่ยนแปลงมาเป็นเวลานาน

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

คุณถูกกดเพื่อเวลา

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

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

บทสรุป

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