我記得我剛開始寫Go的時候
是先跟著前輩一起寫
不過這也是他第一次寫Go project
有天他就跟我說
他把Go project寫成了Java的形狀了
那時候的我一臉茫然,想說他在說什麼???
如果你是從Python跳過來寫GO,應該不會有這種問題
因為你本來就是隻太極鴨,無招勝有招(大誤)(註1)
但如果你是從C#或Java的世界重生到Go的世界
有可能
因為在Go Playground待的不夠久
出新手村就踩到這個大雷
// 介面定義在 Notifier.java 檔案中
public interface Notifier {
void send(String message);
}
// 實作類別定義在 EmailNotifier.java 檔案中
public class EmailNotifier implements Notifier {
@Override
public void send(String message) {
System.out.println("Sending email: " + message);
}
}
// 使用者
public class Main {
public static void main(String[] args) {
Notifier notifier = new EmailNotifier();
notifier.send("Hello, World!");
}
}
// 包名為 email
package email
import "fmt"
// EmailNotifier
type EmailNotifier struct {
}
// 實作 Send 方法
func (e *EmailNotifier) Send(message string) error {
fmt.Println("Sending email:", message)
return nil
}
package main
import (
"myapp/email"
)
// 在使用者端定義 Notifier 介面
type Notifier interface {
Send(message string) error
}
func Notify(n Notifier, message string) error {
return n.Send(message)
}
func main() {
emailNotifier := &email.EmailNotifier{}
Notify(emailNotifier, "Hello, World!")
}
你發現了嗎?
在Golang的世界,使用者在自己世界的中心定義了介面,呼叫了愛情 實作而且是給的是隱隱約約的愛 隱性實作
(Python表示我懂藏在心裡的愛,因為我是隻鴨子) 註1:Duck Typing
而在Java的世界,是工具人送上介面和實作大禮包,並且毫無保留地告訴你,
我用了implements實實在在作了介面
其實這就是
傳說中的SOLID 原則
Interface Segregation Principle(介面隔離原則)
應該將 Interface 拆分成小而專一的部分,讓使用者只需要關注他們實際需要的功能。
你應該讓使用者勇敢地說自己想要的介面
優點如下:
但總有例外,就是開不了口讓你知道
在Go標準庫中
介面通常定義在標準庫的包內,例如 io.Reader、io.Writer、fmt.Stringer 、enconding等。
那為什麼介面定義在「遠離使用者」的位置 ??
註1:Python 沒有明確定義的interface
Duck Typing(鴨子類型)
class EmailNotifier:
def send(self, message):
print(f"Sending email: {message}")
class SMSNotifier:
def send(self, message):
print(f"Sending SMS: {message}")
def notify(notifier, message):
notifier.send(message)
email_notifier = EmailNotifier()
sms_notifier = SMSNotifier()
notify(email_notifier, "Hello via Email!")
notify(sms_notifier, "Hello via SMS!")
Note:在Go的世界,其實你不寫interface在消費者端 ,程式還是能動,但就是不要被人知道