- go沒有類型繼承
- go的繼承不存在is-a關(guān)系
type parent struct {
a int
}
type sub struct {
p parent
a int
}
func NewPeople(p *parent) *parent{
return &p;
}
func (p *parent)dump(){
fmt.Printf("p %s",p.a)
}
func(s *sub)dump(){
fmt.Printf("s %s",s.p.a)
}
func main(){
a := NewPeople(&people{a:1})
// b := NewPeople(&sub{p:p,a:2}) // 會(huì)報(bào)錯(cuò),
b:= sub{parent{a:1},a:2}
b.dump() // 打印不出父類的a值
}
interface的特點(diǎn)
- 不需要顯示聲明關(guān)系,只要兩者方法集有包含關(guān)系,則看做同一類型
solid原則
- SRP 單一職責(zé), 一個(gè)模塊只有一個(gè)功能,一個(gè)文件也要只有一個(gè)功能
- OCP 開閉原則,軟件實(shí)體(類、模塊、函數(shù))應(yīng)該是可擴(kuò)展的,但不可修改,對(duì)擴(kuò)展是開放的,對(duì)修改是關(guān)閉的
- 里氏替換原則LSP,可以用子類替換父類,實(shí)現(xiàn)interface和function type時(shí),不能破壞其對(duì)外的契約,要做到寬進(jìn)嚴(yán)出,即:入?yún)挿?,出參?yán)格控制,子類的校驗(yàn)要比父類更寬泛
- ISP 接口隔離原則,功能相互隔離
- DIP 依賴倒置原則,高層不應(yīng)該依賴底層,底層應(yīng)該依賴于接口,例如A要依賴B,可以把A的依賴改成一個(gè)接口,B去實(shí)現(xiàn)這個(gè)接口
常用設(shè)計(jì)模式
- 工廠方法,創(chuàng)建相關(guān)對(duì)象的時(shí)候,根據(jù)傳參決定創(chuàng)建哪個(gè)對(duì)象
package main
import "fmt"
type cni interface {
createNet()
}
type canai struct {}
func(c canai) createNet(){
fmt.Println("c create net")
}
type calico struct{}
func(c calico) createNet(){
fmt.Println("ca create")
}
func cniFactory(name string)cni {
switch name {
case "canai":
return canai{};
case "calico":
return calico{}
}
}
func main() {
canai := cniFactory("canai")
canai.createNet()
calico := cniFactory("calico")
calico.createNet()
}
- 抽象工廠,創(chuàng)建一組對(duì)象
- 生成器
package main
import "fmt"
type req interface{
send()
}
type cniReq struct {
network string
qos interface{}
multiIP bool
fixIP bool
}
func (c *cniReq) send(){
fmt.Println("send req ")
}
// 用于生成builder
type cniReqBuilder interface {
withNetwork(network string)cniReqBuilder
withQos(qos interfacd) cniReqBuilder
withMultiIP() cniReqBuilder
withFixIP() cniReqBuilder
build() req // 用于生成req
}
type builder struct {
network string
qos interface{}
multiIP bool
fixIP bool
}
// 用于builder對(duì)象屬性的設(shè)置
func (b *builder)withNerwork(network string) cniReqBuilder{
b.network=network
return b
}
func (b *builder)withQos(network interface{}) cniReqBuilder{
b.network=network
return b
}
func (b *builder)withMultiIP() cniReqBuilder{
return b
}
func (b *builder)withFixIP() cniReqBuilder{
return b
}
func(b *builder) build() req {
return &cniReq{
network:b.network,
qos:b.qos,
multiIP:b.multiIP,
fixIP:b.fixIP,
}
}
func NewBuilder() cniReqBuilder {
return builder{}
}
func main() {
// 利用builder創(chuàng)建req
cniReq := NewBuilder().withNetWork("x").
withQos(nil).
withFixIP().
build()
cni.send();
}
- 原型
package main
import "fmt"
type machineTemp struct {
name string
disk int
network string
os string
runtime string
}
func (m *machineTemp) deepCopy() *machineTemp{
return &machineTemp{
name: m.name,
disk:m.disk,
network:m.network,
os:m.os,
runtime:m.runtime
}
}
// 從數(shù)據(jù)庫(kù)等獲取一個(gè)模板,模板不能進(jìn)行修改,所以開始要deepcopy,然后修改copy的對(duì)象
func getMachineTemp()*matchineTemp{
template := getMachineTemp()
t := template.deepCopy()
t.os = "xx"
}
- 單例模式,創(chuàng)建的對(duì)象比較大,又經(jīng)常使用
package main
import (
"fmt"
"sync"
)
var (
globalConf * conf
once = &sync.Once{}
)
type conf struct {
ip string
port int
}
func (c config)getIP() string{
return c.ip
}
func getInstance() *config {
once.Do(func(){
// 這里可能需要解析配置文件,會(huì)比較耗費(fèi)資源,使用單例,只執(zhí)行一次
globalConf = &conf{
ip:"x",
port:1
}
})
return globalConf
}
func main(){
ip:=getInstance().getIP()
port := getInstance().port
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。