เมื่อเราพยายามจะแยกอะไรบางอย่างออกมาเดี่ยวๆ เราจะพบว่ามันถูกผูกติดอยู่กับทุกสิ่งทุกอย่างในจักรวาล

John Muir, My First Summer in the Sierra

ใน Topic 8, ​_The Essence of Good Design_​ เราบอกว่าการใช้หลักการออกแบบที่ดีจะช่วยให้โค้ดที่คุณเขียนนั้นแก้ง่าย Coupling คือศัตรูตัวฉกาจของการเปลี่ยนแปลง เพราะมันผูกมัดสิ่งที่ต้องเปลี่ยนไปพร้อมๆ กันเข้าด้วยกัน ซึ่งทำให้การแก้ไขทำได้ยากขึ้น ไม่ว่าจะเป็นการที่คุณต้องเสียเวลาไล่ตามแก้ทุกส่วนที่เกี่ยวข้องกัน หรือต้องมานั่งสงสัยว่าทำไมพอแก้ "แค่ที่เดียว" แล้วที่อื่นถึงพังตามไปด้วย

เวลาที่คุณออกแบบสิ่งที่ต้องการความแข็งแรง เช่น สะพานหรือหอคอย คุณต้องเชื่อมส่วนประกอบต่างๆ เข้าด้วยกัน:

A link is shown with an interconnected pattern of each component in the link.

ตัวเชื่อมเหล่านี้ทำงานร่วมกันเพื่อให้โครงสร้างมันแข็งแรง

ลองมาเปรียบเทียบกับอะไรแบบนี้ดู:

A link is shown that resembles a tree-like structure.

ที่นี่ไม่มีความแข็งเกร็งเชิงโครงสร้าง: ตัวเชื่อมแต่ละตัวสามารถเปลี่ยนได้ โดยที่ตัวอื่นๆ ก็แค่ปรับตัวตาม

เวลาคุณออกแบบสะพาน คุณต้องการให้มันคงรูปเดิมไว้ คุณต้องการให้มันแข็งแรง (Rigid) แต่เวลาคุณออกแบบซอฟต์แวร์ที่คุณรู้ว่าจะต้องเปลี่ยนในอนาคต คุณต้องการสิ่งที่ตรงกันข้ามเลย นั่นคือคุณต้องการความยืดหยุ่น (Flexible) และเพื่อที่จะให้มันยืดหยุ่นได้ แต่ละคอมโพเนนต์ควรจะเชื่อมต่อ (Couple) กับคอมโพเนนต์อื่นๆ ให้น้อยที่สุดเท่าที่จะเป็นไปได้

และที่แย่ไปกว่านั้น Coupling มันมีสมบัติการถ่ายทอด (Transitive): ถ้า A เชื่อมกับ B และ C, แล้ว B เชื่อมกับ M และ N, และ C เชื่อมกับ X และ Y, นั่นหมายความว่าจริงๆ แล้ว A เชื่อมอยู่กับทั้ง B, C, M, N, X และ Y เลย

ซึ่งนั่นหมายความว่านี่คือหลักการง่ายๆ ที่คุณควรทำตาม:

Tip 44 Decoupled Code Is Easier to Change

ในเมื่อปกติเราไม่ได้เขียนโค้ดด้วยคานเหล็กและหมุดย้ำ แล้วคำว่า Decouple โค้ดมันแปลว่าอะไรล่ะ? ในหัวข้อนี้เราจะมาคุยกันเรื่อง:

  • Train wrecks—การเรียกเมธอดต่อกันเป็นทอดๆ (Chains of method calls)
  • Globalization—อันตรายจากสิ่งที่พึ่งพาค่าคงที่ (Static things)
  • Inheritance—ทำไมการสร้างซับคลาส (Subclassing) ถึงอันตราย

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

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

Train Wrecks