Screen Shot 2558-06-29 at 6.26.35 PM
จากตอนที่ 1 ได้แนะนำเรื่องการออกแบบแบบ Modular ไป
ในตอนที่สองมาดูเรื่องของ SOLID กันหน่อย
เป็นเรื่องเกี่ยวกับ design principle คิดโดย Robert C. Martin หรือ Uncle Bob
ซึ่งเป็นการรวม 5 อย่างไว้ด้วยกัน
ดังนั้นเรามาทำความรู้จักกับ SOLID กันหน่อย

ยิ่งการออกแบบในโลกของ Object-Oriented ด้วยแล้ว
SOLID ยิ่งมีความสำคัญมากๆ
มันคือแนวปฏิบัติที่ช่วยให้ code ทดสอบได้ง่าย

ถ้าใน code แต่ละบรรทัดคุณปฏิบัติตาม SOLID แล้ว
code จะอยู่ในรูปแบบของ modular แน่นอน !!
ดังนั้น มาทำความรู้จักกันดีกว่า

1. S ย่อมาจาก SRP (Single Responsibility Principle)

อธิบายด้วยประโยคสั้นๆ คือ

Class, method ควรจะมีเหตุผลในการเปลี่ยนแปลงเพียงเหตุผลเดียวเท่านั้น

นั่นหมายความว่า ในแต่ละส่วนการทำงานจะต้อง

  • เล็ก
  • ทำงานแบบเฉพาะเจาะจง
  • มีค่า cohesion สูง นั่นคือ เรื่องเดียวกันควรอยู่ด้วยกัน

โดย code ที่ทำตาม SRP นั้น จะทำความเข้าใจได้ง่าย ง่ายต่อการแก้ไข
และเราสามารถเขียน test
เพื่อตรวจสอบพฤติกรรมการทำงานได้ง่าย
ยิ่งไปกว่านั้น ภายใน code จะมีความซับซ้อนต่ำอีกด้วย

โดย SRP นั้นจะมีสองมุมมองคือ
มุมมองแรก
จากภายนอก หรือ ผู้ใช้งาน จะมองว่า
Class และ method มันมีหน้าที่การทำงานเพียงอย่างเดียว

มุมมองที่สอง
จากภายใน จะมองว่า
Class และ method มันมีเพียงเหตุผลเดียวในการเปลี่ยนแปลง

ลองกลับไป code ที่เราสร้างกันขึ้นมาสิว่า
เป็นไปตามแนวคิดของ SRP หรือไม่ อย่างไร ?

2. O ย่อมาจาก OCP (Open-Closed Principle)

อธิบายด้วยประโยคสั้นๆ คือ

เปิดสำหรับการขยาย แต่ปิดสำหรับการแก้ไข !!

เมื่ออ่านดูแล้ว จะพบว่ามัน abstract มาก หรือไม่เข้าใจมันเลย
อะไรว่ะ ?
เปิดสำหรับการเพิ่ม แต่ไม่ให้แก้ไข !!

แต่ความหมายที่แท้จริงของ OCP ก็คือ

เราสามารถทำการเพิ่มความสามารถต่างๆ เข้าไปในระบบ
โดยที่ไม่กระทบกับส่วนอื่นๆ หรือ กระทบให้น้อยที่สุด

เนื่องจากในการพัฒนา software นั้น
เราพบปัญหา classic คือ
เมื่อทำการเพิ่ม feature ใหม่ๆ แล้ว feature เก่าๆ ดันทำงานไม่ได้
เมื่อทำการแก้ไข bug ใหม่ แล้ว bug เก่าๆ ที่เคยแก้ไขไปแล้วมันกลับมา
ปัญหาเหล่านี้ มันเกิดจากการแก้ไข code ทั้งสิ้น
ดังนั้น มันจะดีไหม ถ้าเราเพิ่ม feature โดยไม่ทำการแก้ไข code เดิม

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

3. L ย่อมาจาก LSP (Liscov Substitution Principle)

อธิบายด้วยประโยคสั้นๆ คือ

Sub class หรือ class ลูก ควรมีพฤติกรรมการทำงานตาม Base class หรือ class แม่

โดยที่ LSP นั้นมีเป้าหมายเพื่อจัดการกับลำดับชั้นของ class
เพื่อให้มันมีหน้าที่การทำงานที่ถูกต้อง
นั่นคือทำให้ class ต่างๆ มันสามารถ reuse ได้ง่าย และ เหมาะสม
อีกทั้งยังทำให้การทดสอบง่ายขึ้นอีก

ซึ่งการทดสอบจะเรียกว่า Contract testing
นั่นคือจะทำการทดสอบผ่านพวก interface หรือ abstraction layer แทนส่วน implement จริงๆ

4. I ย่อมาจาก ISP (Interface Segregation Principle)

อธิบายด้วยประโยคสั้นๆ คือ

Client หรือผู้ใช้งาน ควรผูกติดกับ interface ของตัวเองไปเลย
มากกว่าใช้ interface ที่มันเป็น standard ของทุกๆ ส่วน

เรามักพบปัญหาว่า abstraction layer หรือ interface ส่วนใหญ่
ถูกสร้างขึ้นมา เพื่อกำหนดมาตรฐานของ component ต่างๆ
แต่บ่อยครั้ง เราพบว่ามีหลาย method ที่ไม่ถูกใช้งาน
นั่นหมายความว่า interface ที่เราใช้มันไม่ได้เหมาะสมกับ client เลย

ดังนั้น สิ่งที่เราควรทำก็คือ
ปรับเปลี่ยนแนวคิด เพื่อสร้าง interface ให้เหมาะสมกับแต่ละ client ไปซะ
นั่นคือ เราจะมี interface เล็กๆ เพียบเลย !!

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

5. D ย่อมาจาก DIP (Dependency Inversion Principle)

อธิบายด้วยประโยคสั้นๆ คือ

Code แต่ละส่วนควรขึ้นอยู่กับ abstraction layer
และไม่ควรขึ้นอยู่กับส่วนการ implementation

ยิ่งฟังมันก็ยิ่งงงกันไปใหญ่เลย
DIP นั้นมันแนะนำใหเราหลีกเลี่ยงการสร้าง object ภายใน code
เช่นการใช้ new ใน code นั่นเอง

เนื่องจากเราทำให้ code ในระบบมันผูกมัดกันอย่างมาก (Tight coupling)
ดังนั้นให้ทำการเปลี่ยนด้วยการส่ง object ที่เราต้องการใช้เข้าไปแทน
โดยการพัฒนาจะใช้ abstraction layer หรือ interface แทน
ส่งผลให้ code มันไม่ผูกติดกัน (Loose coupling)

ส่วนการเขียน test นั้นเรามักส่งสิ่งที่เราต้องการ
มายังส่วนที่เราต้องการทดสอบ
วิธีการนั้นเรียกว่า Dependency Injection ซึ่งประกอบไปด้วย

  • Constructor injection
  • Property injection
  • Method injection

ส่งผลทำให้การทดสอบทำได้ง่าย และ ยึดหยุ่นขึ้นมาก

สุดท้ายแล้ว

ในฐานนะที่เราเป็นนักพัฒนา software
ควรมีความรู้ความเข้าใจเกี่ยวกับแนวคิดในการออกแบบ
และสามารถนำมันมาใช้ประโยชน์ได้
ไม่ใช่แค่เรียนรู้อย่างเดียวนะครับ !!

และอย่าลืมศึกษาความรู้ในเรื่องอื่นๆเพิ่มเติมด้วย

Tags: