什么是循环依赖
其实就 package A 引入了 package B ,然后 package B 又引入了 package A ,因此形成了循环依赖。
现象如下:
测试代码
package A import ( "strings" B “/GoProject/main/gobase/cycle/b" ) func Foo(a string) (string) { return B.Add(a) } func Minus(a string) (string) { return strings.Trim(a, "\t") }
package B import A "GoProject/main/gobase/cycle/a" func Goo(a string) (string) { return A.Minus(a) } func Add(a string) (string) { return a + "----" }
运行测试代码:
package cycle import ( "testing" A "GoProject/main/gobase/cycle/a" ) func TestCycle(t *testing.T) { A.Foo("good") }
运行结果:
packageGoProject/main/gobase/cycle (test) imports /GoProject/main/gobase/cycle/a importsGoProject/main/gobase/cycle/b imports GoProject/main/gobase/cycle/a: import cycle not allowed FAIL
外观模式实现
我们之前的java设计模式中介绍到了外观模式,发现这在很有用 我首先将包A,B中的方法抽象成接口,将方法先隔离出来
package service type A interface { Minus(s string) (string) } type B interface { Add(s string) (string) }
然后我A,B实现接口。为了容易处理,定义两个结构体进行处理。
package A import ( "strings" "github.com/hundred666/GoTest/service" ) type AImpl struct { b service.B } func (a *AImpl) Foo(s string) (string) { return a.b.Add(s) } func (a *AImpl) Minus(s string) (string) { return strings.Trim(s, "\t") }
B的设计如下:
package B import "github.com/hundred666/GoTest/service" type BImpl struct { a service.A } func (b *BImpl) Goo(a string) (string) { return b.a.Minus(a) } func (b *BImpl) Add(a string) (string) { return a + "----" }
实现了方法,得能够将实例化的变量分别放入A,B结构体中,因此A需要实现以下方法
func NewA() *AImpl { return new(AImpl) } func (a *AImpl) SetB(b service.B) { a.b = b }
B需要实现以下方法
func NewB() *BImpl { return new(BImpl) } func (b *BImpl) SetA(a service.A) { b.a = a }
需要调用的时候就可以去调用了
package main import ( "github.com/hundred666/GoTest/B" "github.com/hundred666/GoTest/A" "fmt" ) func main() { b := B.NewB() a := A.NewA() a.SetB(b) r := a.Foo("aa") fmt.Println(r) }