0Pricing
Swift Academy · บทเรียน

นามธรรมที่อิงตามโพรโทคอล

พึ่งพาโพรโทคอล ไม่ใช่ชนิดรูปธรรม

นามธรรมที่อิงตามโพรโทคอล เป็นบทเรียน Swift Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Swift Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน

นามธรรมที่อิงตามโปรโตคอล

การฉีดโปรโตคอลแทนชนิดรูปธรรมทำให้คุณสลับการนำไปใช้ได้อย่างอิสระ ผู้ใช้จะพึ่งพาเฉพาะพฤติกรรม ไม่ใช่คลาส

กำหนดโปรโตคอล

อธิบายความสามารถด้วยโปรโตคอล ชนิดใดก็ตามที่สอดคล้องกับโปรโตคอลสามารถนำมาใช้เป็นสิ่งพึ่งพาได้

protocol Logging {
    func log(_ message: String)
}
print("Protocol describes behavior, not a concrete class.")

ทำให้ชนิดรูปธรรมสอดคล้องกับโปรโตคอล

การนำไปใช้จริงจะสอดคล้องกับโปรโตคอล และเป็นสิ่งพึ่งพาสำหรับระบบจริง

protocol Logging { func log(_ m: String) }
struct ConsoleLogger: Logging {
    func log(_ m: String) { print("LOG: \(m)") }
}
ConsoleLogger().log("ready")

พึ่งพาโปรโตคอล

ชนิดของพร็อพเพอร์ตีในผู้ใช้คือโปรโตคอล จึงรับค่าใด ๆ ที่สอดคล้องกับโปรโตคอลได้

protocol Logging { func log(_ m: String) }
struct ConsoleLogger: Logging { func log(_ m: String) { print(m) } }
struct Service {
    let logger: Logging // protocol, not ConsoleLogger
    func run() { logger.log("running") }
}
Service(logger: ConsoleLogger()).run()

สลับการนำไปใช้

เนื่องจากชนิดนั้นเป็นโปรโตคอล คุณจึงส่งการนำไปใช้แบบอื่นที่สอดคล้องกันได้ โดยไม่ต้องแก้ไขผู้ใช้

protocol Logging { func log(_ m: String) }
struct Loud: Logging { func log(_ m: String) { print(m.uppercased()) } }
struct Quiet: Logging { func log(_ m: String) {} }
struct Service { let logger: Logging; func run() { logger.log("hi") } }
Service(logger: Loud()).run()
Service(logger: Quiet()).run()

การเขียนโปรแกรมโดยอิงอินเทอร์เฟซ

นี่คือหลักการ “พึ่งพานามธรรม ไม่ใช่รูปธรรม” โค้ดระดับสูงจึงไม่ต้องรับรู้รายละเอียดระดับต่ำ

protocol Storage { func save(_ v: Int) }
struct MemoryStore: Storage { func save(_ v: Int) { print("kept \(v)") } }
struct Manager { let store: Storage; func add() { store.save(1) } }
Manager(store: MemoryStore()).add()

ผู้ที่สอดคล้องหลายชนิด

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

protocol Source { func value() -> Int }
struct Fixed: Source { func value() -> Int { 10 } }
struct Doubler: Source { func value() -> Int { 20 } }
func use(_ s: Source) { print(s.value()) }
use(Fixed())
use(Doubler())

โปรโตคอลที่มีพฤติกรรมหลายแบบ

โปรโตคอลสามารถประกาศเมธอดได้หลายรายการ เพื่อสร้างข้อตกลงที่ชัดเจนสำหรับสิ่งพึ่งพา

protocol Cache {
    func get(_ key: String) -> Int?
    func set(_ key: String, _ v: Int)
}
struct Dict: Cache {
    var store: [String: Int] = [:]
    func get(_ k: String) -> Int? { store[k] }
    mutating func set(_ k: String, _ v: Int) { store[k] = v }
}
var c = Dict(); c.set("a", 1)
print(c.get("a") ?? -1)

ข้อจำกัดแบบทั่วไป

คุณยังสามารถฉีดผ่านพารามิเตอร์แบบทั่วไปที่มีข้อจำกัดเป็นโปรโตคอลได้ ซึ่งช่วยหลีกเลี่ยงต้นทุนเพิ่มเติมจากการใช้ชนิดแบบนามธรรม

protocol Greeter { func greet() -> String }
struct English: Greeter { func greet() -> String { "Hello" } }
struct Welcome<G: Greeter> {
    let greeter: G
    func show() { print(greeter.greet()) }
}
Welcome(greeter: English()).show()

ข้อตกลงที่คงที่

ตราบใดที่โปรโตคอลยังคงเสถียร การนำไปใช้ภายในก็เปลี่ยนแปลงได้โดยไม่ทำให้ผู้ใช้เสียหาย

protocol Formatter { func format(_ n: Int) -> String }
struct Plain: Formatter { func format(_ n: Int) -> String { "\(n)" } }
struct Padded: Formatter { func format(_ n: Int) -> String { String(format: "%03d", n) } }
func render(_ f: Formatter) { print(f.format(7)) }
render(Plain())
render(Padded())

เตรียมพร้อมสำหรับการจำลอง

ที่สำคัญ โปรโตคอลทำให้การทดสอบสามารถจัดเตรียมชนิดจำลองที่สอดคล้องกันมาแทนชนิดจริงได้ นี่คือหัวข้อหลักของบทเรียนถัดไป

protocol Network { func fetch() -> String }
struct Real: Network { func fetch() -> String { "server data" } }
struct VM { let net: Network; func load() { print(net.fetch()) } }
VM(net: Real()).load()

ตรวจสอบความเข้าใจ

เหตุใดจึงฉีดชนิดโปรโตคอลแทนคลาสรูปธรรม

สรุปทบทวน

การฉีดโปรโตคอลช่วยซ่อนชนิดรูปธรรม ทำให้สามารถแทนที่ด้วยชนิดใด ๆ ที่สอดคล้องกันได้ วิธีนี้เป็นไปตามหลัก “พึ่งพานามธรรม” และรองรับการนำไปใช้ทางเลือก รวมถึงชนิดจำลองสำหรับการทดสอบ ที่สำคัญ บทถัดไป: การจำลองสิ่งพึ่งพาในการทดสอบ

คำถามที่พบบ่อย

บทเรียน “นามธรรมที่อิงตามโพรโทคอล” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “นามธรรมที่อิงตามโพรโทคอล” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Swift Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “นามธรรมที่อิงตามโพรโทคอล”

พึ่งพาโพรโทคอล ไม่ใช่ชนิดรูปธรรม คุณปฏิบัติ Swift Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Swift Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Swift Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “นามธรรมที่อิงตามโพรโทคอล” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Swift Academy นี้ได้ไหม

ได้ บทเรียน Swift Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. เหตุผลที่ใช้การฉีดการพึ่งพา
  2. การฉีดผ่านตัวสร้าง
  3. นามธรรมที่อิงตามโพรโทคอล
  4. การจำลองการพึ่งพาในการทดสอบ
← กลับไปที่ Swift Academy