Golang Interface - مقدماتی
اینترفیس به طور کلی یعنی روشی که بشه باهاش رفتار یه ابجکت رو تعریف کرد و ابجکت هم باید تمام اون رفتار ها رو انجام بده. و آبجکت خودش تصمیم میگیره چگونه این رفتار هارو انجام بده. برای مثال, ماشین لباسشویی ۲ تا رفتار شستن و خشک کردن داره. هر مدل ماشین لباسشوئی باید این ۲ رفتار رو انجام بده ولی به روش خودشون.
- برای ساده سازی تمام کد ها داخل یک فایل نوشته شدن
- go version go1.14.4 darwin/amd64
حالا اولین قسمت کد را با هم بررسی می کنیم:
package main
import (
"fmt"
)
//interface definition
type WashingMachine interface {
Clean() string
Dry() string
}
type SamsungModel struct {
model string
}
//SamsungModel implements Clean
func (s SamsungModel) Clean() string {
return fmt.Sprintf("Samsung model %s is cleaning", s.model)
}
//SamsungModel implements Dry
func (s SamsungModel) Dry() string {
return fmt.Sprintf("Samsung model %s is drying", s.model)
}
func main() {
wm := SamsungModel{"SM001"}
var v WashingMachine
v = wm
fmt.Println(v.Clean())
fmt.Println(v.Dry())
}
اولین قسمت کد تعریف اینترفیس `WashingMachine` است. که مشخص میکنه هر مدل ماشین لباسشویی باید ۲ تا کار `Clean` و `Dry` را حتمن انجام بده. حالا صرف نظر از تعریف اینترفیس, میایم مدل `SamsungModel` را تعریف میکنیم. قسمت مهم کد `v = wm` هست که تایید میکنه `SamsungModel`باید از اینترفیس `WashingMachine` تبعیت کنه. خود `SamsungModel` تصمیم میگیرد که متد های `Clean`و `Dry` را چگونه پیاده سازی کنن ولی نوع خروجی هر کدام باید به اینترفیس یکسان باشن. خروجی کد بالا باید همچین چیزی باشه:
Samsung model SM001 is cleaning
Samsung model SM001 is drying
حالا بیایم یه مدل جدید اضافه کنیم:
package main
import (
"fmt"
)
//interface definition
type WashingMachine interface {
Clean() string
Dry() string
}
type SamsungModel struct {
model string
}
//SamsungModel implements Clean
func (s SamsungModel) Clean() string {
return fmt.Sprintf("Samsung model %s is cleaning", s.model)
}
//SamsungModel implements Dry
func (s SamsungModel) Dry() string {
return fmt.Sprintf("Samsung model %s is drying", s.model)
}
type LGModel struct {
model string
year int
}
//LGModel implements Clean
func (l LGModel) Clean() string {
return fmt.Sprintf("LG model %s, year %d is cleaning", l.model, l.year)
}
//LGModel implements Dry
func (l LGModel) Dry() string {
return fmt.Sprintf("LG model %s, year %d is drying", l.model, l.year)
}
func main() {
wm := SamsungModel{"SM001"}
var v WashingMachine
v = wm
wm2 := LGModel{"LG001", 2020}
var v2 WashingMachine
v2 = wm2
fmt.Println(v.Clean())
fmt.Println(v.Dry())
fmt.Println(v2.Clean())
fmt.Println(v2.Dry())
}
کاری که کردیم دقیقن مثل حالت اول هست با این تغییر که مدل جدید روشه خودش رو برای `Clean` و `Dry` انجام میده. ولی ساختن مدل به این روش تمیز نیست. بیاین یکم ساختن مدل هارو ساده تر کنیم. فانکشن `main` نهایتا میشه :
func main() {
wm := SamsungModel{"SM001"}
wm2 := LGModel{"LG001", 2020}
models := []WashingMachine{wm, wm2}
fmt.Println(models[0].Clean())
fmt.Println(models[0].Dry())
}
حالا میشه یه فانکشن نوشت که هر ۲ مدل بتونن ازش استفاده کنن والی جز اینترفیس نباشه:
...
func list(wm WashingMachine) {
fmt.Println(wm.Clean())
fmt.Println(wm.Dry())
}
func main() {
wm := SamsungModel{"SM001"}
var v WashingMachine = wm
list(v)
}
مطلبی دیگر از این انتشارات
نوع متغییر تابع در go
مطلبی دیگر از این انتشارات
الگوهای طراحی در زبان گو (Design patterns in go)-مقدمه
مطلبی دیگر از این انتشارات
خلاصه مختصر مفید GoLang (پارت اول)