การประกอบ interface และแนวทางปฏิบัติที่ดี
interface ขนาดเล็กและการกลับทิศทางดีเพนเดนซี
การประกอบ interface และแนวทางปฏิบัติที่ดี เป็นบทเรียน Go Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Go Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
การประกอบอินเทอร์เฟซ
อินเทอร์เฟซของ Go สามารถฝังอินเทอร์เฟซอื่นเพื่อประกอบเป็นอินเทอร์เฟซที่มีขนาดใหญ่ขึ้นได้:
package main
import "io"
// io.ReadWriter composes Reader and Writer
type ReadWriter interface {
io.Reader
io.Writer
}
// Your own composition:
type Processor interface {
io.Reader
Process() error
io.Closer
}
func main() { _ = (*Processor)(nil) }หลักการอินเทอร์เฟซขนาดเล็ก
อินเทอร์เฟซของ Go ที่ทรงพลังที่สุดมักมีเมธอดหนึ่งหรือสองรายการ ซึ่งทำให้มีชนิดข้อมูลจำนวนมากที่สุดที่สามารถทำตามอินเทอร์เฟซนั้นได้:
io.Reader— 1 เมธอดio.Writer— 1 เมธอดerror— 1 เมธอดfmt.Stringer— 1 เมธอด
อินเทอร์เฟซขนาดใหญ่สร้างตัวจำลองและทำการทดสอบได้ยากกว่า
การกลับทิศทางการพึ่งพา
รับอินเทอร์เฟซในพารามิเตอร์ของฟังก์ชันแทนชนิดข้อมูลรูปธรรม วิธีนี้ทำให้โค้ดไม่ผูกติดกับการนำไปใช้งานเฉพาะแบบ:
package main
import "fmt"
type Store interface {
Get(key string) (string, bool)
Set(key, val string)
}
func cache(s Store, key, value string) {
if _, ok := s.Get(key); !ok {
s.Set(key, value)
}
}
type MapStore struct{ m map[string]string }
func (ms *MapStore) Get(k string) (string, bool) { v, ok := ms.m[k]; return v, ok }
func (ms *MapStore) Set(k, v string) { ms.m[k] = v }
func main() {
s := &MapStore{m: map[string]string{}}
cache(s, "x", "hello")
v, _ := s.Get("x")
fmt.Println(v)
}การแยกอินเทอร์เฟซ
แยกอินเทอร์เฟซขนาดใหญ่ออกเป็นอินเทอร์เฟซขนาดเล็กที่มุ่งเน้นเฉพาะด้าน ผู้เรียกใช้จะพึ่งพาเฉพาะเมธอดที่ตนใช้งาน:
package main
// Bad: large interface forces all methods
type BigStorage interface {
Read(key string) string
Write(key, val string)
Delete(key string)
List() []string
Backup() error
}
// Good: small, focused interfaces
type Reader interface{ Read(key string) string }
type Writer interface{ Write(key, val string) }
type Lister interface{ List() []string }
func readAll(r Reader) {} // only needs Read
func main() { _ = readAll }การคืนค่าชนิดข้อมูลรูปธรรม
ฟังก์ชันสร้างควรคืนค่าชนิดข้อมูลรูปธรรม ไม่ใช่อินเทอร์เฟซ ผู้เรียกใช้สามารถกำหนดชนิดข้อมูลรูปธรรมให้กับตัวแปรอินเทอร์เฟซได้เสมอ:
package main
type Logger interface{ Log(string) }
type ConsoleLogger struct{}
func (c *ConsoleLogger) Log(s string) {}
// Good: return concrete *ConsoleLogger
func NewConsoleLogger() *ConsoleLogger { return &ConsoleLogger{} }
// Avoid: return Logger (hides the concrete type)
// func NewConsoleLogger() Logger { return &ConsoleLogger{} }
func main() { _ = NewConsoleLogger() }การสร้างอินเทอร์เฟซมากเกินไป
อย่าสร้างอินเทอร์เฟซให้ทุกชนิดข้อมูลเพียงเพราะอาจต้องใช้ในอนาคต สร้างอินเทอร์เฟซเฉพาะเมื่อ:
- ตอนนี้หรือในเร็ว ๆ นี้มีการนำไปใช้งานหลายแบบ
- จำเป็นต้องสร้างตัวจำลองของสิ่งที่พึ่งพาในการทดสอบ
- กำลังสร้างไลบรารีและต้องการแยกผู้เรียกใช้ออกจากรายละเอียดการนำไปใช้งาน
การฝังอินเทอร์เฟซเพื่อขยายการทำงาน
ฝังอินเทอร์เฟซเพื่อเพิ่มเมธอดเสริมที่มีการทำงานเริ่มต้น:
package main
import "fmt"
type Handler interface{ Handle(msg string) }
type NamedHandler interface {
Handler
Name() string
}
func dispatch(h Handler) {
if nh, ok := h.(NamedHandler); ok {
fmt.Printf("[%s] ", nh.Name())
}
h.Handle("event")
}
type MyHandler struct{}
func (m MyHandler) Handle(msg string) { fmt.Println(msg) }
func (m MyHandler) Name() string { return "my" }
func main() { dispatch(MyHandler{}) }การสร้างตัวจำลองด้วยอินเทอร์เฟซ
กำหนดสิ่งที่พึ่งพาเป็นอินเทอร์เฟซ แล้วใส่ตัวจำลองในการทดสอบ:
package main
import "fmt"
type Clock interface{ Now() int64 }
type MockClock struct{ T int64 }
func (m MockClock) Now() int64 { return m.T }
func isExpired(c Clock, expiresAt int64) bool {
return c.Now() > expiresAt
}
func main() {
mc := MockClock{T: 1000}
fmt.Println(isExpired(mc, 500)) // true
fmt.Println(isExpired(mc, 1500)) // false
}การฝังอินเทอร์เฟซเทียบกับการฝังโครงสร้างเพื่อใช้ซ้ำ
ใช้การฝังอินเทอร์เฟซเพื่อประกอบส่วนติดต่อการใช้งาน และใช้การฝังโครงสร้างเพื่อใช้โค้ดซ้ำ ทั้งสองมีจุดประสงค์ต่างกันและไม่ควรสับสนกัน
การตรวจสอบการทำตามอินเทอร์เฟซขณะคอมไพล์
ใช้การตรวจสอบขณะคอมไพล์ด้วยตัวระบุว่าง เพื่อยืนยันว่าชนิดข้อมูลของคุณทำตามอินเทอร์เฟซที่กำหนด:
package main
type Doer interface{ Do() }
type MyType struct{}
func (m *MyType) Do() {}
// Compile-time check — no runtime cost
var _ Doer = (*MyType)(nil)
func main() {}ตรวจสอบอย่างรวดเร็ว
คุณควรกำหนดอินเทอร์เฟซใหม่ใน Go เมื่อใด
สรุปทบทวน: แนวทางปฏิบัติที่ดีสำหรับอินเทอร์เฟซ
ประเด็นสำคัญ:
- ทำให้อินเทอร์เฟซมีขนาดเล็ก — มีเมธอดหนึ่งหรือสองรายการ
- ประกอบอินเทอร์เฟซจากอินเทอร์เฟซขนาดเล็ก
- รับอินเทอร์เฟซและคืนค่าชนิดข้อมูลรูปธรรม
- สร้างอินเทอร์เฟซเพื่อให้ทดสอบได้และรองรับการนำไปใช้งานหลายแบบ
- ใช้การตรวจสอบด้วยการกำหนดค่าให้ตัวระบุว่างขณะคอมไพล์
โจทย์ฝึกปฏิบัติ
ออกแบบอินเทอร์เฟซ Notifier ที่มี Notify(msg string) error แล้วนำไปใช้กับ EmailNotifier และ SMSNotifier เขียนฟังก์ชัน broadcast ที่ส่งข้อความไปยัง []Notifier
เรียนรู้ Go ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 51
- บทเรียน
- 203
คำถามที่พบบ่อย
บทเรียน “การประกอบ interface และแนวทางปฏิบัติที่ดี” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การประกอบ interface และแนวทางปฏิบัติที่ดี” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Go Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การประกอบ interface และแนวทางปฏิบัติที่ดี”
interface ขนาดเล็กและการกลับทิศทางดีเพนเดนซี คุณปฏิบัติ Go Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Go Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Go Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “การประกอบ interface และแนวทางปฏิบัติที่ดี” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Go Academy นี้ได้ไหม
ได้ บทเรียน Go Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การกำหนดและใช้งาน interface
- interface ของไลบรารีมาตรฐานหลัก
- การยืนยันชนิดข้อมูลและสวิตช์ชนิดข้อมูล
- การประกอบ interface และแนวทางปฏิบัติที่ดี