Quantcast
Channel: cc :: somkiat
Viewing all articles
Browse latest Browse all 1997

จัดการ Dependency Injection ด้วย Dagger 2

$
0
0

Dagger2

Dagger2 จากบทความเรื่อง Dependency Injection Made Simple ทำการอธิบายเรื่อง Dependency Injection และ Dependency Inversion Principle (DIP) ทำให้เข้าใจว่าวิธีการนี้มีความสำคัญอย่างไรต่อการพัฒนา software สิ่งที่น่าสนใจคือ การจัดการ Dependency Injection ในระบบงานด้วย Dagger ซึ่งเป็น library ที่นักพัฒนาหลาย ๆ คนไม่น่าจะพลาด โดยเฉพาะ Android Developer น่าจะรู้จักและใช้งานกันเกือบทุกคน !!
ในบทความข้างต้นใช้ Dagger 1 แต่ในบทความนี้ใช้ Dagger 2 นะครับ
ดังนั้นเรามาดูในรายละเอียดว่ามีอะไรที่น่าสนใจบ้าง
  • Dagger 1 นั้นถูกพัฒนาและดูแลจาก Square
  • Dagger 2 นั้นถูก fork มาจาก Dagger 1 ซึ่งดูแลโดย Google

สำหรับ Android app แนะนำให้ใช้ Dagger 2 นะ

เนื่องจาก Dagger 1 นั้นมีปัญหากับ proguard เพราะว่าใน code มีการใช้ Reflection API จำนวนมาก และ code จะ generate ออกมาดูยากมาก ๆ ส่วน Dagger 2 นั้นทำการแก้ไขปัญหาข้างต้นให้เรียบร้อย ส่วนการพัฒนาระบบด้วยภาษา Java ก็ใช้งานได้เช่นกัน ซึ่งจะอยู่ในตัวอย่างด้านล่างต่อไป

คำแนะนำสำหรับการใช้งาน Dagger 2 นั้น

ควรทำความรู้จักและเข้าใจเกี่ยวกับ Dependency Injection ก่อนนะ มิเช่นนั้นคุณจะรู้เพียงว่า ทำแบบนี้แล้วทำงานได้ แต่ไม่ได้เข้าใจเลยว่า การทำงานเป็นอย่างไร ? ซึ่งเป็นปัญหาอย่างหนึ่งที่มักพบเจอในการพัฒนา software !! (รู้แต่ไม่เข้าใจ) บทความเพิ่มเติมเกี่ยวกับ Depencey Injection

อธิบาย Dependency Injection ให้เข้าใจง่าย ๆ คือ

เราจะไม่ทำการสร้าง object ของ class ที่ต้องการใช้งานเอง ตัวอย่างเช่น [gist id="3013226898763fd6594382ae5a263d80" file="NormalDI.java"] เมื่อ dependency class เริ่มมีเยอะ ๆ แล้ว เราน่าจะมีการจัดกลุ่มและทำการสร้าง object เหล่านั้นให้เลย ซึ่ง class นี้จะเรียกว่า Factory หรือโรงงานผลิต object นั่นเอง ตัวอย่างเช่น [gist id="3013226898763fd6594382ae5a263d80" file="WorkWithFactory.java"] เมื่อต้องการเรียกใช้งาน dependency ต่าง ๆ ก็เรียกใช้งาน ผ่าน Factory กันไปเลย ดังตัวอย่าง [gist id="3013226898763fd6594382ae5a263d80" file="Main.java"]

จะเห็นได้ว่าใน Factory ต้องเขียน code แบบเดิม ๆ สำหรับ dependency ทุกตัว

มันน่าเบื่อมาก ๆ code ซ้ำ ๆ ซาก ๆ ดังนั้นจึงมีคนคิด library ต่าง ๆ ขึ้นมา เพื่อลดจำนวน code ลงไป หนึ่งในนั้นคือ Dagger แต่ในบทความนี้จะเน้นไปที่ Dagger 2 เริ่มด้วยการใช้งาน @Inject สำหรับ Dependency Injection กัน มีอยู่ 3 แบบ คือ
  • Constructor Injection
  • Field Injection
  • Method Injection
ตัวอย่างเช่น [gist id="3013226898763fd6594382ae5a263d80" file="DemoDI.java"]

ปัญหาต่อมาคือ แล้วจะไปเอา Object ของ Dependency มาจากไหนล่ะ ?

ในตัวอย่างแรกมี Factory class สำหรับเตรียมและสร้าง object ต่าง ๆ เมื่อมาใช้ Dagger 2 แล้วก็ต้องจัดการเช่นกัน ซึ่งจะใช้งานผ่าน Module และ Component โดยโครงสร้างของ dependency ต่าง ๆ ถูกนำเสนอในรูปแบบของ graph ที่เป็นแบบ Directed Acyclic Graph (DAG) มันคือ directed graph ที่ไม่เกิด cyclic นั่นเอง ซึ่งเป็นที่มาของชื่อ Dagger นั่นเอง แสดงดังรูป AcyclicDigraphs_800 มาดูรายละเอียดของทั้งคู่กันนิดหน่อย

Module คือ Factory นั่นเอง

สามารถแบ่ง dependency ต่าง ๆ ออกเป็นกลุ่ม เพื่อให้ง่ายต่อการจัดการและใช้งาน รวมทั้งเชื่อมโยง dependency ต่าง ๆ เข้าด้วยกัน แถมสามารถอ้างอิงไปยัง Module อื่น ๆ ได้อีก ตัวอย่างเช่น [gist id="3013226898763fd6594382ae5a263d80" file="FirstModule.java"]

Component คือ ประตูหรือทางเข้าใช้งาน

สิ่งต่าง ๆ ที่กำหนดไว้ผ่าน annotation @Injection และ @Provides เทียบง่าย ๆ ก็คือ interface นั่นเอง ซึ่ง interface ไม่สามารถสร้าง object ได้ ดังนั้น Dagger 2 จึงทำการสร้าง class มาให้ใช้งาน มีรูปแบบชื่อ class ดังนี้ DaggerComponentName ตัวอย่างเช่น [gist id="3013226898763fd6594382ae5a263d80" file="FirstComponent.java"] จากนั้นให้ทำการ run ด้วยคำสั่ง [code] mvn clean install exec:java -Dexec.mainClass="demo.di.Main" [/code]

จากตัวอย่างจะเห็นว่าเมื่อนำแนวคิด Dependency Injection มาใช้แล้ว

ทั้ง class MyClass, Dependency1 และ Dependency2 นั้น แยกการทำงานออกจากกันชัดเจนมาก (Loose coupling) ทำให้แต่ละส่วนทำงานเป็นอิสระมากขึ้น ทำให้จัดการได้ง่ายและสะดวกขึ้น ทำให้ทดสอบได้ง่ายขึ้น แต่ปัญหาที่ตามมาและหลีกเลี่ยงไม่ได้คือ ความซับซ้อนที่สูงขึ้น จำนวน class/interface มากขึ้น ระบบงานเริ่มมี magic มากขึ้น ทำให้ learning curve สูงขึ้น
ดังนั้นก่อนจะเริ่มใช้งานอะไร ขอแนะนำให้ศึกษาเรื่องพื้นฐานก่อนเสมอ อย่าใช้เพียงเพราะว่าเขาบอกว่า ฟังมาว่า มันดี !!
สามารถดู source code ของตัวอย่างได้จาก Github::MyDagger2 และสามารถดูตัวอย่าง code เพิ่มเติมเรื่องการชงกาแฟ เป็นตัวอย่างจาก Dagger 2 :: Coffee อธิบายได้ชัดเจนมาก โดยแสดงการทำงานดังรูป dagger-example
ในบทความต่อไปจะเป็นตัวอย่างในการพัฒนา Android app มีส่วนการทำงานหรือ dependency ต่าง ๆ เยอะมาก ทั้ง Activity, Fragment, Service รวมทั้ง 3-parties library ต่าง ๆ อีก มาดูกันว่าสามารถจัดการด้วย Dagger 2 กันอย่างไร

Viewing all articles
Browse latest Browse all 1997

Trending Articles