nattapong99 / book

0 stars 0 forks source link

Part 1: What is Dependency Injection? #5

Open nattapong99 opened 6 years ago

nattapong99 commented 6 years ago

What is Dependency Injection?

บทความนี้เป็นเรื่องทั่วไปเกี่ยวกับ Dependency Injection และการใช้งานคอนเทนเนอร์ใน PHP โดยเฉพาะ

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

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

01

จากโค้ดข้างบนจะจัดเก็บข้อมูลภาษาของผู้ใช้ไว้ในตัวแปร language session ดังนั้นสำหรับ request ที่ตามมาทั้งหมดของผู้ใช้รายเดียวกัน language นั้นจะพร้อมใช้งานตัวแปรแบบ global $ _SESSION array

02

ในฐานะที่ Dependency Injection มีความหมายเฉพาะในโลก Object-Oriented ลองสมมติว่าเรามีคลาส SessionStorage ที่รวบรวมกลไก PHP session

03

และคลาส User นำมาใช้งาน

04

การใช้งานคลาส User ทำได้ง่าย ๆ ดังตัวอย่าง

05

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

Hardcode ชื่อลงไปในคลาส User ใน constuctor SessionStorage

06

กำหนดค่า constant นอกคลาส User

07

เพิ่มตัวแปร $sessionName ไปใน User constructor

08

เพิ่ม array option ไปในคลาส storage

09

ทางเลือกทั้งหมดที่มีนั้นเป็นทางเลือกที่ค่อนข้างแย่ Hardcode session name ในคลาส User ไม่ใช่การแก้ปัญหาที่แท้จริงเนื่องจากหากมีการเปลี่ยนอีกคุณก็ต้องกลับมาแก้ไขคลาส User อยู่ดี ใช้ constant เป็นไอเดียที่แย่เนื่องจากจะทำให้คลาส User ขึ้นอยู่กับค่า constant ที่กำหนด การส่ง session name เป็น argument หรือ array option อาจเป็นทางเลือกที่ดี แต่ยังไม่ดีที่สุดเนื่องจากทำให้ argument ของ constructor ของคลาส User ยุ่งเกี่ยวกับ object ที่ไม่ใช้ตัวมันเอง

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

ใช้ Dependency Injection แทนที่การสร้าง SessionStorage object ภายในคลาส User โดยการ inject SessionStorage object ไปใน User object โดยการส่งมันเป็น argument constructor

10

นี่คือการ Dependency Injection การใช้คลาส User คุณต้องสร้าง SessionStorage object ขึ้นมาก่อน

11

ตอนนี้การกำหนดค่าของ session storage object ก็เป็นเรื่องง่าย อีกทั้งการเปลี่ยนคลาสก็สามารถทำได้ง่ายมาก ๆ ด้วยเช่นกัน และทั้งหมดนี้เราไม่ต้องแก้ไขเปลี่ยนแปลงคลาส User เลย

Dependency Injection มีสามรูปแบบ

Consturctor Injection

12

Setter Injection

13

Property Injection

14

จากทั้งสามแบบนี้ constructor injection ดีที่สุดสำหรับการใช้คลาสต่าง ๆ เช่นในตัวอย่าง ส่วน setter injection ดีที่สุดสำหรับการกำหนดค่าให้คลาสต่าง ๆ เช่นกำหนดค่า cache object สำหรับ instance

ปัจจุบัน PHP framework สมัยใหม่ใช้ Dependency Injection เพื่อเปลี่ยนการผูกติดกันของคลาสให้แยกเป็นชิ้นส่วนประกอบต่าง ๆ กันแทน

15

source