การฉีดผ่านตัวสร้าง
ส่งการพึ่งพาผ่านตัวเริ่มต้น
การฉีดผ่านตัวสร้าง เป็นบทเรียน Swift Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Swift Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
การฉีดผ่านตัวสร้าง
รูปแบบ DI ที่ใช้บ่อยที่สุดคือการส่งสิ่งพึ่งพาผ่านตัวเริ่มต้น อ็อบเจ็กต์จะได้รับทุกสิ่งที่ต้องใช้ตั้งแต่เวลาสร้าง และจัดเก็บสิ่งเหล่านั้นไว้
init พื้นฐาน
ประกาศพร็อพเพอร์ตีที่จัดเก็บค่า แล้วกำหนดค่าให้ใน init ผู้เรียกต้องส่งสิ่งพึ่งพาเข้ามาเพื่อสร้างอ็อบเจ็กต์
struct Greeter { func hi() -> String { "Hi" } }
struct View {
let greeter: Greeter
init(greeter: Greeter) { self.greeter = greeter }
func show() { print(greeter.hi()) }
}
View(greeter: Greeter()).show()สิ่งพึ่งพาที่เปลี่ยนแปลงไม่ได้
การใช้ let กับพร็อพเพอร์ตีที่ถูกฉีดเข้ามาทำให้พร็อพเพอร์ตีเปลี่ยนแปลงไม่ได้ ดังนั้นจึงเปลี่ยนสิ่งพึ่งพาหลังการสร้างไม่ได้
struct Engine { let hp: Int }
struct Car {
let engine: Engine // cannot change later
init(engine: Engine) { self.engine = engine }
}
let c = Car(engine: Engine(hp: 150))
print(c.engine.hp)สิ่งพึ่งพาหลายรายการ
ระบุพารามิเตอร์หลายรายการเพื่อฉีดสิ่งที่ทำงานร่วมกันมากกว่าหนึ่งรายการ ตัวเริ่มต้นจะบอกข้อกำหนดทั้งหมดอย่างชัดเจน
struct DB { func get() -> Int { 7 } }
struct Cache { func put(_ v: Int) { print("cached \(v)") } }
struct Service {
let db: DB
let cache: Cache
init(db: DB, cache: Cache) { self.db = db; self.cache = cache }
func run() { cache.put(db.get()) }
}
Service(db: DB(), cache: Cache()).run()ค่าเริ่มต้นของพารามิเตอร์
ค่าเริ่มต้นทำให้ผู้เรียกไม่ต้องระบุสิ่งพึ่งพาในระบบจริง แต่ยังสามารถแทนที่ค่าได้ในการทดสอบ
struct Logger { func log(_ m: String) { print(m) } }
struct Service {
let logger: Logger
init(logger: Logger = Logger()) { self.logger = logger }
func run() { logger.log("go") }
}
Service().run() // uses defaultการฉีดผ่านตัวสร้างของคลาส
คลาสใช้รูปแบบเดียวกัน ตัวเริ่มต้นจะกำหนดสิ่งพึ่งพาแต่ละรายการก่อนที่อินสแตนซ์จะพร้อมใช้งาน
class Mailer { func send() { print("sent") } }
class Signup {
let mailer: Mailer
init(mailer: Mailer) { self.mailer = mailer }
func go() { mailer.send() }
}
Signup(mailer: Mailer()).go()การฉีดค่า
สิ่งพึ่งพาไม่จำเป็นต้องเป็นอ็อบเจ็กต์ คุณสามารถฉีดค่าการกำหนดค่า เช่น URL พื้นฐานหรือแฟล็ก ด้วยวิธีเดียวกันได้
struct Client {
let baseURL: String
init(baseURL: String) { self.baseURL = baseURL }
func endpoint(_ p: String) -> String { baseURL + p }
}
print(Client(baseURL: "https://api").endpoint("/users"))จุดประกอบ
จุดหนึ่งใกล้กับจุดเริ่มต้นของ app จะเชื่อมต่อกราฟอ็อบเจ็กต์ทั้งหมด ส่วนอื่น ๆ เพียงรับสิ่งพึ่งพาที่เตรียมไว้แล้ว
struct DB { func count() -> Int { 3 } }
struct Repo { let db: DB; func n() -> Int { db.count() } }
struct App { let repo: Repo; func run() { print(repo.n()) } }
// Composition root:
let app = App(repo: Repo(db: DB()))
app.run()หลีกเลี่ยงโกลบอลที่ซ่อนอยู่
การฉีดผ่านตัวสร้างเข้ามาแทนที่การเข้าถึงโกลบอลที่ซ่อนอยู่ สิ่งพึ่งพาแต่ละรายการจึงชัดเจน ทำให้คุณติดตามการไหลของข้อมูลได้
struct Settings { let theme: String }
struct Screen {
let settings: Settings
func render() { print("Theme: \(settings.theme)") }
}
Screen(settings: Settings(theme: "dark")).render()จำเป็นกับไม่บังคับ
หากสิ่งพึ่งพาเป็นทางเลือกอย่างแท้จริง ให้จำลองด้วยชนิดทางเลือก มิฉะนั้นให้กำหนดเป็นสิ่งจำเป็น เพื่อไม่ให้อ็อบเจ็กต์อยู่ในสภาพที่กำหนดค่าไม่ครบ
struct Analytics { func track() { print("tracked") } }
struct Flow {
let analytics: Analytics?
func step() { analytics?.track() }
}
Flow(analytics: Analytics()).step()
Flow(analytics: nil).step()เหตุผลที่ใช้การฉีดผ่านตัวสร้าง
วิธีนี้รับประกันว่าอ็อบเจ็กต์จะเริ่มต้นอย่างสมบูรณ์ ทำให้สิ่งพึ่งพามองเห็นได้ และทำงานร่วมกับความไม่เปลี่ยนแปลงของ let ได้ จึงเป็นค่าเริ่มต้นที่แนะนำใน Swift
struct Adder { func add(_ a: Int, _ b: Int) -> Int { a + b } }
struct Calc {
let adder: Adder
init(adder: Adder) { self.adder = adder }
}
print(Calc(adder: Adder()).adder.add(4, 5))ตรวจสอบความเข้าใจ
เหตุใดจึงมักนิยมใช้การฉีดผ่านตัวสร้าง
สรุปทบทวน
การฉีดผ่านตัวสร้าง ส่งสิ่งพึ่งพาผ่าน init และจัดเก็บไว้ โดยมักใช้พร็อพเพอร์ตี let ที่เปลี่ยนแปลงไม่ได้ คุณสามารถฉีดอ็อบเจ็กต์หรือค่า ระบุค่าเริ่มต้น และเชื่อมต่อทุกอย่างที่จุดประกอบได้ บทถัดไปจะแสดงการฉีดโปรโตคอลแทนชนิดรูปธรรม
คำถามที่พบบ่อย
บทเรียน “การฉีดผ่านตัวสร้าง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การฉีดผ่านตัวสร้าง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Swift Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การฉีดผ่านตัวสร้าง”
ส่งการพึ่งพาผ่านตัวเริ่มต้น คุณปฏิบัติ Swift Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Swift Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Swift Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “การฉีดผ่านตัวสร้าง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Swift Academy นี้ได้ไหม
ได้ บทเรียน Swift Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ