interface Notifier — hợp đồng thay được
🧠 Suy nghĩ
"Hôm nay gửi Telegram, mai có thể sếp yêu cầu gửi Slack, mốt là Email. Vậy phải viết sao để thay đổi dễ dàng?"
Câu trả lời của Go: Interface — bản hợp đồng "ai làm được việc này thì tham gia".
📐 Logic
- Định nghĩa hợp đồng: "Notifier là bất cứ ai có hàm
SendAlert(message)" - Viết một thực thể cụ thể:
TelegramBot— có hàmSendAlert, tức là thoả mãn hợp đồng - Sau này thêm
SlackBot,EmailBot… chỉ cần chúng cũng cóSendAlertlà dùng được
💻 Code
// HỢP ĐỒNG: Ai có hàm SendAlert(message) error thì là một Notifier
type Notifier interface {
SendAlert(message string) error
}
// THỰC THỂ cụ thể
type TelegramBot struct {
ChannelID string
}
// TelegramBot có hàm SendAlert → tự động là Notifier (không cần khai báo "implements" như Java)
func (t TelegramBot) SendAlert(message string) error {
fmt.Printf("🚨 [Telegram %s]: %s\n", t.ChannelID, message)
return nil
}
🔍 Giải thích
- Go không cần từ khoá
implements. Chỉ cần struct có đủ method của interface → tự động khớp. Gọi là duck typing: "Nếu nó kêu quạc quạc như vịt thì nó là vịt". - Trả về
errorvì gửi mạng có thể thất bại — Go bắt bạn phải nghĩ đến lỗi. - Ở đây trả
nilvì demo → không lỗi.
🎁 Lợi ích thực tế
Mai muốn đổi sang Slack? Chỉ cần viết:
type SlackBot struct{ Webhook string }
func (s SlackBot) SendAlert(msg string) error { ... }
Code chính không đổi 1 dòng.