Protocol và cơ chế Delegate trong Swift

Một phần của tài liệu Giáo trình lập trình di động trên iOS Dành cho bậc Cao đẳng (Trang 46 - 49)

1.2 Ngôn ngữ lập trình Swift

1.2.16 Protocol và cơ chế Delegate trong Swift

Protocol trong Swift là một kiểu dùng để định nghĩa cho các chức năng (không định

nghĩa việc lưu trữ dữ liệu), hay nói cách khác, Protocol là một cách để chúng ta định nghĩa các API cho phép nơi gọi tự định nghĩa chức năng mà họ mong muốn. Điều này giúp chương trình linh hoạt hơn giống như việc dùng các interfaces trong ngôn ngữ Java. Cú pháp định nghĩa cho Protocol có dạng:

protocol <protocolName> {

<requirements> }

Trong đó <requirements> là định nghĩa prototype của các hàm (API) cho protocol. Ví dụ dưới đây sẽ định nghĩa một Protocol chứa hàm random của một Generator. Hàm này không nhận đối truyền vào và trả về một giá trị Double (chỉ là dạng prototype):

protocol RandomNumberGenerator {

func random() -> Double }

Tuỳ nhu cầu sử dụng mà ở các lớp kế thừa nó sẽ tự định nghĩa ra các loại hàm sinh số ngẫu nhiên khác nhau theo các thuật tốn khác nhau. Ví dụ, ta có thể xây dựng một lớp có tên LinearCongruentialGenerator để tạo số ngẫu nhiên có giá trị trong khoảng từ 0 đến 1 (nhỏ hơn 1) theo thuật toán đồng dư tuyến tính (Linear congruential generator): // Algorithm linear congruential generator

class LinearCongruentialGenerator: RandomNumberGenerator {

var lastRandom = 42.0 let m = 139968.0 let a = 3877.0 let c = 29573.0

// Thực hiện chức năng hàm random

func random() -> Double {

lastRandom = ((lastRandom * a + c) .truncatingRemainder(dividingBy:m)) return lastRandom / m

} }

let generator = LinearCongruentialGenerator()

print("Here's a random number: \(generator.random())")

// Prints "Here's a random number: 0.3746499199817101"

print("And another one: \(generator.random())")

// Prints "And another one: 0.729023776863283"

Lưu ý: Nếu muốn các API của protocol có thể thay đổi các biến thể của lớp định nghĩa

nó thì cần đưa từ khoá mutating vào trước func.

Cơ chế Delegate (Uỷ quyền) trong Swift

Trong Swift, nhiều thư viện đối tượng được xây dựng sẵn để sử dụng. Tuy nhiên, nhiều chức năng của chúng lại không thể xây dựng trước (do nhu cầu người dùng là khác nhau). Cơ chế uỷ quyền sẽ giúp ta giải quyết vấn đề này.

Xét ví dụ sau: Viết chương trình mơ phỏng mối quan hệ giữa cửa hàng sản xuất bánh

quy và cửa hàng bán bánh quy ra thị trường. Trước tiên chúng ta định nghĩa cấu trúc dữ liệu của một chiếc bánh quy như sau:

struct Cookie {

var size:Int = 5

var hasChocolateChips:Bool = false }

40

Tiếp theo, chúng ta định nghĩa cửa hàng sản xuất bánh quy như sau:

class Bakery

{

func makeCookie() {

var cookie = Cookie() cookie.size = 6

cookie.hasChocolateChips = true }

}

Lớp này có một hàm để tạo ra những chiếc bánh quy theo yêu cầu. Tuy nhiên, để bán những chiếc bánh này lại không phải chức năng của cửa hàng làm bánh mà là chức năng của cửa hàng bán bánh. Điều này gây khó khăn cho việc tổ chức chương trình vì mỗi khi bánh được làm xong, nó cần được bán nhưng ta lại không thể định nghĩa chức năng này trong cửa hàng sản xuất bánh được, vì đó là chức năng của cửa hàng bán bánh. Cơ chế uỷ quyền sẽ giải quyết vấn đề này.

Trước tiên, ta cần định nghĩa Protocol có chứa chức năng bán của cửa hàng bán bánh:

protocol BakeryDelegate {

func sellingCookie(_ cookie: Cookie) }

Và hàm sellingCookie() sẽ được gọi mỗi khi cửa hàng làm bánh sản xuất xong. Để thực hiện điều đó, chúng ta điều chỉnh lại định nghĩa cho cửa hàng làm bánh như sau:

class Bakery

{

var delegate:BakeryDelegate? func makeCookie()

{

var cookie = Cookie() cookie.size = 6

cookie.hasChocolateChips = true delegate?.sellingCookie(cookie) }

}

Trong đó có hai điều chỉnh: Thêm một biến delegate có kiểu là Protocol mới định nghĩa ở trên (có chứa chức năng bán bánh) và gọi chức năng bán bánh này mỗi khi cửa hàng sản xuất xong. Nhưng ở đây của hàng bán bánh không cần biết bánh sẽ được bán như thế nào (nghĩa là lớp này khơng có trách nhiệm định nghĩa hàm bán bánh hoạt động ra sao) mà nó sẽ uỷ quyền việc đó cho cửa hàng bán bánh thực hiện. Định nghĩa nhu sau:

class CookieShop: BakeryDelegate // Lớp cửa hàng bán bánh

{

func sellingCookie(_ cookie: Cookie) {

print("Buy cookie, with size \(cookie.size)!") }

Cuối cùng chạy chương trình như sau:

let shop = CookieShop() // Tạo cửa hàng bán bánh let bakery = Bakery() // Tạo cửa hàng làm bánh

bakery.delegate = shop // Uỷ quyền bán cho shop bakery.makeCookie() // Thực hiện sản xuất bánh

Mỗi khi bánh được sản xuất xong thì nó sẽ được bán ngay bởi cửa hàng shop và dòng sau đây sẽ hiện trên màn hình kết quả: Buy cookie, with size 6!

Một phần của tài liệu Giáo trình lập trình di động trên iOS Dành cho bậc Cao đẳng (Trang 46 - 49)

Tải bản đầy đủ (PDF)

(137 trang)