Protocol — คืออะไร, โปรโตคอลและดีลิเกตใน iOS

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-02-18 เวลาอ่าน: 10 นาที

Protocol คือชุดของข้อกำหนด (คุณสมบัติและเมธอด) ที่ชนิดที่รับโปรโตคอลไปใช้ต้องปฏิบัติตาม ใน Swift โปรโตคอลเป็นองค์ประกอบหลักของ Protocol-Oriented Programming (POP) ซึ่งช่วยให้เกิดพหุสัณฐานโดยไม่ต้องสืบทอด ตามข้อมูลจาก Swift.org (2025) โปรโตคอลถูกใช้ใน 85% ของชนิดในไลบรารีมาตรฐานของ Swift ใน Objective-C นั้น @protocol มีบทบาทคล้ายกัน แต่มีข้อจำกัด — สำหรับคลาสเท่านั้น

ประเด็นสำคัญ

  • Protocol — สัญญาที่กำหนดอินเทอร์เฟซที่โครงสร้าง คลาส หรือการแจงนับต้องนำไปใช้
  • Protocol-Oriented Programming — กระบวนทัศน์ Swift ที่โปรโตคอลและส่วนขยายโปรโตคอลแทนที่ลำดับชั้นการสืบทอดที่ลึก
  • Protocol extension — การใช้งานเมธอดเริ่มต้น ทำให้เมธอดของโปรโตคอลเป็นทางเลือกโดยไม่ต้องใช้ @objc
  • Associated types — โปรโตคอลทั่วไปที่มีชนิดเชื่อมโยงสำหรับการทำงานที่ปลอดภัยชนิดกับข้อมูลประเภทต่างๆ
  • Protocol composition — การรวมหลายโปรโตคอลผ่านตัวดำเนินการ & สำหรับการระบุข้อกำหนดที่แม่นยำ

โปรโตคอลใน Swift คืออะไร?

Protocol ใน Swift คืออินเทอร์เฟซนามธรรมที่กำหนดข้อกำหนดซึ่งชนิดต้องปฏิบัติตาม โปรโตคอลสามารถกำหนดคุณสมบัติ (พร้อม getter/setter), เมธอด (ของอินสแตนซ์และของชนิด), ตัวเริ่มต้น และ subscript ต่างจากคลาส โปรโตคอลสามารถรับไปใช้โดยโครงสร้าง การแจงนับ และคลาส — ให้ความยืดหยุ่นที่ไม่มีในภาษาที่ใช้คลาสล้วนๆ

Swift
protocol Drawable {
    var boundingRect: CGRect { get }
    mutating func draw(in context: CGContext)
}

struct Circle: Drawable {
    var center: CGPoint
    var radius: CGFloat
    
    var boundingRect: CGRect {
        CGRect(x: center.x - radius, y: center.y - radius,
               width: radius * 2, height: radius * 2)
    }
    
    func draw(in context: CGContext) {
        context.addEllipse(in: boundingRect)
    }
}

โครงสร้าง Circle รับโปรโตคอล Drawable ไปใช้ โดยให้คุณสมบัติ boundingRect และเมธอด draw(in:) ต้องขอบคุณโปรโตคอล ทำให้รูปร่างใดๆ ที่ใช้งาน Drawable สามารถจัดการได้อย่างเป็นเอกภาพ — นี่คือพหุสัณฐานโดยไม่ต้องสืบทอดจากคลาสพื้นฐานร่วม

Protocol-Oriented Programming: กระบวนทัศน์ Swift

Protocol-Oriented Programming (POP) คือกระบวนทัศน์ที่ Apple นำเสนอใน WWDC 2015 เป็นทางเลือกแทนการสืบทอดแบบคลาส ใน POP โปรโตคอลเป็นเครื่องมือหลักในการทำให้เป็นนามธรรม และส่วนขยายโปรโตคอลให้การใช้งานเริ่มต้น ซึ่งแก้ปัญหา «การสืบทอดรูปเพชร» และช่วยให้สามารถขยายชนิดที่มีอยู่ได้โดยไม่ต้องแก้ไขซอร์สโค้ด

ด้านPOP (เชิงโปรโตคอล)OOP (เชิงคลาส)
หน่วยนามธรรมProtocolคลาสพื้นฐาน
กลไกการใช้ซ้ำProtocol extensionการสืบทอด
ชนิดค่ารองรับ (struct)เฉพาะชนิดอ้างอิง
การรับไปใช้หลายครั้งProtocol compositionการสืบทอดหลายทาง (ไม่มีใน Swift)
ความเสี่ยงการเชื่อมโยงต่ำ (การเชื่อมโยงหลวม)สูง (ลำดับชั้นแข็งเกร็ง)

ตามบล็อก Apple Swift (2025) โครงสร้างคิดเป็น 70% ของชนิดในแอปพลิเคชัน Swift สมัยใหม่ POP เป็นเหตุผลหลักของการเปลี่ยนแปลงนี้: โปรโตคอลช่วยให้โครงสร้างได้รับพฤติกรรมพหุสัณฐานโดยไม่ต้องเปลี่ยนไปใช้คลาส

โปรโตคอลเทียบกับคลาสนามธรรมเทียบกับอินเทอร์เฟซ

โปรโตคอล Swift อยู่ตรงกลางระหว่างอินเทอร์เฟซ Java และคลาสนามธรรม C++ สามารถมีการใช้งานได้ (ผ่านส่วนขยาย) แต่ไม่สามารถมีสถานะ (คุณสมบัติที่เก็บไว้) มาดูความแตกต่างระหว่างสามภาษากัน

ลักษณะSwift ProtocolJava InterfaceC++ Abstract Class
การใช้งานเมธอดได้ (extension)ได้ (default methods)ได้
คุณสมบัติที่เก็บไว้ไม่ได้ไม่ได้ได้
ชนิดค่าได้ไม่ได้ไม่ได้
การใช้งานหลายทางได้ได้ได้
ตัวเริ่มต้นได้ (ข้อกำหนด)ไม่ได้ได้

ความแตกต่างหลัก: Swift Protocol สามารถกำหนดตัวเริ่มต้นและ subscript ซึ่งไม่มีใน Java Interface อย่างไรก็ตาม โปรโตคอลไม่สามารถเก็บสถานะได้ — นี่ยังคงเป็นความรับผิดชอบของชนิดที่รับโปรโตคอลไปใช้

Associated Types และ Generics ในโปรโตคอล

Associated Type (ชนิดเชื่อมโยง) คือชนิดทั่วไปภายในโปรโตคอลที่ถูกทำให้เป็นรูปธรรมโดยชนิดที่รับไปใช้ ซึ่งช่วยให้สร้างโปรโตคอลที่ปลอดภัยชนิดได้โดยไม่ต้องระบุชนิดข้อมูลที่เป็นรูปธรรม ชนิดเชื่อมโยงทำงานควบคู่กับเจเนอริกของ Swift

Swift
protocol Container {
    associatedtype Item
    var count: Int { get }
    mutating func append(_ item: Item)
    subscript(i: Int) -> Item { get }
}

struct IntStack: Container {
    var items: [Int] = []
    var count: Int { items.count }
    typealias Item = Int
    
    mutating func append(_ item: Int) {
        items.append(item)
    }
    
    subscript(i: Int) -> Int {
        items[i]
    }
}

func sum<C: Container>(_ container: C) -> C.Item where C.Item: Numeric {
    // เนื้อความของฟังก์ชัน
}

Container คือโปรโตคอลที่มี associatedtype Item IntStack นำไปใช้โดยระบุ typealias Item = Int ฟังก์ชันเจเนอริก sum ใช้ where clause เพื่อทำงานเฉพาะกับคอนเทนเนอร์ตัวเลข ชนิดเชื่อมโยงทำให้โปรโตคอลเป็นทั่วไปโดยไม่สูญเสียความปลอดภัยของชนิด

Protocol composition และส่วนขยายโปรโตคอล

Protocol composition — การรวมหลายโปรโตคอลผ่านตัวดำเนินการ & ชนิดที่สอดคล้องกับองค์ประกอบต้องใช้งานโปรโตคอลที่รวมกันทั้งหมด ซึ่งแทนที่การสืบทอดหลายทางที่ไม่มีใน Swift และช่วยให้ระบุข้อกำหนดของพารามิเตอร์ฟังก์ชันได้อย่างแม่นยำ

Swift
protocol Named { var name: String { get } }
protocol Aged { var age: Int { get } }

struct Person: Named, Aged {
    let name: String
    let age: Int
}

func greet(_ entity: Named & Aged) {
    print("สวัสดี, \(entity.name), อายุ \(entity.age)!")
}

// Protocol extension — การใช้งานเริ่มต้น
extension Named {
    func introduce() {
        print("ฉันชื่อ \(name)")
    }
}

Protocol extension ให้การใช้งานเมธอดเริ่มต้น ชนิดที่รับโปรโตคอลไปใช้สามารถแทนที่เมธอดของส่วนขยายได้ — ในกรณีนั้น การใช้งานของตัวเองจะถูกเรียก นี่คือกลไกที่ Swift ใช้ในการimplement เมธอดที่เป็นทางเลือกโดยไม่ต้องใช้ @objc

@protocol ใน Objective-C: ความแตกต่างจาก Swift

@protocol ใน Objective-C เป็นรุ่นก่อนของ Swift Protocol แต่มีข้อจำกัดที่สำคัญ โปรโตคอล Objective-C ใช้ได้เฉพาะกับคลาสเท่านั้น (ไม่ใช่โครงสร้างหรือการแจงนับ) และใช้การจัดส่งแบบไดนามิกผ่านการส่งข้อความ เมธอดสามารถเป็น @required (ค่าเริ่มต้น) หรือ @optional

Objective-C
@protocol Loggable
@required
- (void)logMessage: (NSString *)message;
@optional
- (NSString *)logPrefix;
@end

@interface ConsoleLogger : NSObject 
@end

@implementation ConsoleLogger
- (void)logMessage: (NSString *)message {
    NSLog(@"[LOG] %@", message);
}
@end

ต่างจาก Swift โปรโตคอล Objective-C ไม่รองรับชนิดเชื่อมโยง เจเนอริก ส่วนขยายโปรโตคอล หรือชนิดค่า โปรโตคอลเหล่านี้ยังคงเป็นกลไกนามธรรมเชิงคลาส ในขณะที่ Swift Protocol เป็นเครื่องมือพหุสัณฐานที่เต็มเปี่ยมสำหรับทุกชนิด

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

โปรโตคอลแตกต่างจากคลาสนามธรรมอย่างไร?

Protocol ไม่สามารถเก็บสถานะ (คุณสมบัติที่เก็บไว้) — ได้เพียงข้อกำหนดคุณสมบัติเท่านั้น คลาสนามธรรมสามารถมีฟิลด์ข้อมูลได้ โปรโตคอลสามารถรับไปใช้โดยโครงสร้างและการแจงนับ ในขณะที่คลาสนามธรรมสามารถเป็นคลาสย่อยได้โดยคลาสเท่านั้น ใน Swift โปรโตคอลเป็นเครื่องมือนามธรรมหลัก คลาสถูกใช้น้อยกว่า

Protocol-Oriented Programming คืออะไร?

POP คือกระบวนทัศน์ที่โปรโตคอลและส่วนขยายโปรโตคอลแทนที่ลำดับชั้นการสืบทอดที่ลึก แทนที่จะใช้คลาสพื้นฐานที่คลาสย่อยทั้งหมดสืบทอด POP ใช้องค์ประกอบของโปรโตคอลกับการใช้งานเริ่มต้นผ่านส่วนขยาย ซึ่งลดการเชื่อมโยงและปรับปรุงการนำโค้ดกลับมาใช้ใหม่

โปรโตคอลสามารถสืบทอดโปรโตคอลอื่นได้หรือไม่?

ได้ โปรโตคอล Swift รองรับการสืบทอด protocol SerializableDrawable: Drawable, Codable — โปรโตคอลที่รวมข้อกำหนดของ Drawable และ Codable ชนิดที่รับ SerializableDrawable ไปใช้ต้องปฏิบัติตามข้อกำหนดของโปรโตคอลทั้งหมดในลำดับชั้น ซึ่งแตกต่างจากการสืบทอดคลาส — โปรโตคอลไม่มีบรรพบุรุษร่วมกัน

any และ some ในบริบทของโปรโตคอลคืออะไร?

some (ชนิดทึบแสง) รับประกันว่าฟังก์ชันคืนชนิดเฉพาะที่สอดคล้องกับโปรโตคอล any (ชนิดอัตถิภาวนิยม) อนุญาตให้เก็บชนิดใดๆ ที่สอดคล้องกับโปรโตคอล some ใช้เพื่อรักษาเอกลักษณ์ของชนิด any ใช้สำหรับคอลเลกชันที่ต่างชนิดกัน some ปรากฏใน Swift 5.1 any ปรากฏใน Swift 5.7

จะตรวจสอบความสอดคล้องกับโปรโตคอลใน Swift ได้อย่างไร?

ใช้ is สำหรับตรวจสอบและ as? สำหรับการแปลง: if let drawable = object as? Drawable { drawable.draw(in: ctx) } ใน Objective-C ใช้ conformsToProtocol: Swift รองรับการตรวจสอบ is สำหรับโปรโตคอลที่ไม่มีชนิดเชื่อมโยงด้วย

สรุป

  • Protocol — สัญญาที่กำหนดข้อกำหนดสำหรับคุณสมบัติ เมธอด ตัวเริ่มต้น และ subscript สำหรับชนิดที่รับไปใช้
  • Protocol-Oriented Programming แทนที่การสืบทอดคลาสด้วยองค์ประกอบโปรโตคอลและส่วนขยาย
  • Protocol extension ให้การใช้งานเริ่มต้น ทำให้เมธอดเป็นทางเลือกโดยไม่ต้องใช้ @objc
  • Associated types ช่วยให้สร้างโปรโตคอลทั่วไปที่มีการทำให้ชนิดเป็นรูปธรรมที่ฝั่งการใช้งาน
  • Protocol composition ผ่าน & รวมข้อกำหนดของหลายโปรโตคอล
  • Objective-C @protocol จำกัดเฉพาะคลาสและไม่รองรับชนิดเชื่อมโยง เจเนอริก หรือชนิดค่า
  • คำแนะนำ: ใช้โปรโตคอลเป็นเครื่องมือนามธรรมหลักใน Swift โดยใช้คลาสเฉพาะเมื่อต้องการความหมายของการอ้างอิง

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม