什么是循环依赖

其实就 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)
}
复制代码

参考资料