- go没有类型继承
- go的继承不存在is-a关系
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}) // 会报错,
b:= sub{parent{a:1},a:2}
b.dump() // 打印不出父类的a值
}
interface的特点
- 不需要显示声明关系,只要两者方法集有包含关系,则看做同一类型
solid原则
- SRP 单一职责, 一个模块只有一个功能,一个文件也要只有一个功能
- OCP 开闭原则,软件实体(类、模块、函数)应该是可扩展的,但不可修改,对扩展是开放的,对修改是关闭的
- 里氏替换原则LSP,可以用子类替换父类,实现interface和function type时,不能破坏其对外的契约,要做到宽进严出,即:入参宽泛,出参严格控制,子类的校验要比父类更宽泛
- ISP 接口隔离原则,功能相互隔离
- DIP 依赖倒置原则,高层不应该依赖底层,底层应该依赖于接口,例如A要依赖B,可以把A的依赖改成一个接口,B去实现这个接口
常用设计模式
- 工厂方法,创建相关对象的时候,根据传参决定创建哪个对象
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()
}
- 抽象工厂,创建一组对象
- 生成器
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对象属性的设置
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创建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
}
}
// 从数据库等获取一个模板,模板不能进行修改,所以开始要deepcopy,然后修改copy的对象
func getMachineTemp()*matchineTemp{
template := getMachineTemp()
t := template.deepCopy()
t.os = "xx"
}
- 单例模式,创建的对象比较大,又经常使用
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(){
// 这里可能需要解析配置文件,会比较耗费资源,使用单例,只执行一次
globalConf = &conf{
ip:"x",
port:1
}
})
return globalConf
}
func main(){
ip:=getInstance().getIP()
port := getInstance().port
}
网友评论