golang自动生成PlantUML类图与接口关系图插件库GoPlantUML的使用

GoPlantUML V2

GoPlantUML 是一个开源的 Go 语言工具,用于从 Go 源代码自动生成 PlantUML 类图和接口关系图。它可以帮助开发者可视化 Go 项目中的结构和关系,提高代码理解和文档编写的效率。

安装

前提条件:

  • Go 1.17 或更高版本

安装命令:

go get github.com/jfeliu007/goplantuml/parser
go install github.com/jfeliu007/goplantuml/cmd/goplantuml@latest

这将在你的 GOPATH bin 文件夹中安装 goplantuml 命令。

使用

基本用法:

goplantuml [-recursive] path/to/gofiles path/to/gofiles2

将输出保存到文件:

goplantuml [-recursive] path/to/gofiles path/to/gofiles2 > diagram_file_name.puml

可用选项:

- aggregate-private-members
       Show aggregations for private members. Ignored if -show-aggregations is not used.
- hide-connections
       hides all connections in the diagram
- hide-fields
       hides fields
- hide-methods
       hides methods
- ignore string
       comma separated list of folders to ignore
- notes string
       Comma separated list of notes to be added to the diagram
- output string
       output file path. If omitted, then this will default to standard output
- recursive
       walk all directories recursively
- show-aggregations
       renders public aggregations even when -hide-connections is used (do not render by default)
- show-aliases
       Shows aliases even when -hide-connections is used
- show-compositions
       Shows compositions even when -hide-connections is used
- show-connection-labels
       Shows labels in the connections to identify the connections types (e.g. extends, implements, aggregates, alias of
- show-implementations
       Shows implementations even when -hide-connections is used
- show-options-as-note
       Show a note in the diagram with the none evident options ran with this CLI
- title string
       Title of the generated diagram
- hide-private-members
       Hides all private members (fields and methods)

示例

生成示例图:

goplantuml $GOPATH/src/github.com/jfeliu007/goplantuml/parser

这将输出类似下面的 PlantUML 代码:

@startuml
namespace parser {
    class Struct {
        + Functions []*Function
        + Fields []*Parameter
        + Type string
        + Composition []string
        + Extends []string
    }
    class LineStringBuilder {
        + WriteLineWithDepth(depth int, str string) 
    }
    class ClassParser {
        - structure map[string]map[string]*Struct
        - currentPackageName string
        - allInterfaces map[string]struct{}
        - allStructs map[string]struct{}

        - structImplementsInterface(st *Struct, inter *Struct) 
        - parsePackage(node ast.Node) 
        - parseFileDeclarations(node ast.Decl) 
        - addMethodToStruct(s *Struct, method *ast.Field) 
        - getFunction(f *ast.FuncType, name string) 
        - addFieldToStruct(s *Struct, field *ast.Field) 
        - addToComposition(s *Struct, fType string) 
        - addToExtends(s *Struct, fType string) 
        - getOrCreateStruct(name string) 
        - getStruct(structName string) 
        - getFieldType(exp ast.Expr, includePackageName bool) 

        + Render() 
    }
    class Parameter {
        + Name string
        + Type string
    }
    class Function {
        + Name string
        + Parameters []*Parameter
        + ReturnValues []string
    }
}
strings.Builder *-- parser.LineStringBuilder
@enduml

保存到文件:

goplantuml $GOPATH/src/github.com/jfeliu007/goplantuml/parser > ClassDiagram.puml

关系类型

GoPlantUML 识别两种主要关系:

  1. 接口实现关系
  2. 类型组合关系

示例代码:

package testingsupport

//MyInterface only has one method, notice the signature return value
type MyInterface interface {
	foo() bool
}

//MyStruct1 will implement the foo() bool function so it will have an "extends" association with MyInterface
type MyStruct1 struct {
}

func (s1 *MyStruct1) foo() bool {
	return true
}

//MyStruct2 will be directly composed of MyStruct1 so it will have a composition relationship with it
type MyStruct2 struct {
	MyStruct1
}

//MyStruct3 will have a foo() function but the return value is not a bool, so it will not have any relationship with MyInterface
type MyStruct3 struct {
    Foo MyStruct1
}

func (s3 *MyStruct3) foo() {
}

生成的 PlantUML:

@startuml
namespace testingsupport {
    interface MyInterface  {
        - foo() bool
    }
    class MyStruct1 << (S,Aquamarine) >> {
        - foo() bool
    }
    class MyStruct2 << (S,Aquamarine) >> {
    }
    class MyStruct3 << (S,Aquamarine) >> {
        - foo() 
        + Foo MyStruct1
    }
}
testingsupport.MyStruct1 *-- testingsupport.MyStruct2
testingsupport.MyInterface <|-- testingsupport.MyStruct1
testingsupport.MyStruct3 o-- testingsupport.MyStruct1
@enduml

渲染图表示例

示例 UML 图

要渲染这些图,你可以使用 PlantUML 的在线服务器或本地安装的 PlantUML。


更多关于golang自动生成PlantUML类图与接口关系图插件库GoPlantUML的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang自动生成PlantUML类图与接口关系图插件库GoPlantUML的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


GoPlantUML - 自动生成PlantUML类图与接口关系图

GoPlantUML是一个用于从Go代码自动生成PlantUML类图和接口关系图的工具库。它能分析Go代码结构并生成可视化的UML图表,非常适合文档化和理解项目架构。

安装

go get github.com/jfeliu007/goplantuml

基本使用

1. 生成单个包的类图

package main

import (
	"fmt"
	"github.com/jfeliu007/goplantuml/parser"
	"github.com/jfeliu007/goplantuml/renderer"
)

func main() {
	// 解析指定目录的Go代码
	p := parser.NewParser()
	err := p.ParseDir("./example")
	if err != nil {
		panic(err)
	}

	// 创建渲染器
	r := renderer.NewPlantUMLRenderer()

	// 生成UML内容
	uml, err := r.Render(p.GetParsedData())
	if err != nil {
		panic(err)
	}

	fmt.Println(uml)
}

2. 生成整个项目的类图

func main() {
	p := parser.NewParser()
	
	// 递归解析整个项目
	err := p.ParseRecursive("./", []string{"vendor", "testdata"})
	if err != nil {
		panic(err)
	}

	r := renderer.NewPlantUMLRenderer()
	uml, err := r.Render(p.GetParsedData())
	if err != nil {
		panic(err)
	}

	// 将结果写入文件
	err = os.WriteFile("output.puml", []byte(uml), 0644)
	if err != nil {
		panic(err)
	}
}

高级功能

1. 自定义渲染选项

r := renderer.NewPlantUMLRendererWithOptions(renderer.Options{
	ShowStructFields:   true,   // 显示结构体字段
	ShowMethods:        true,   // 显示方法
	ShowInterfaces:      true,   // 显示接口
	ShowCompositions:    true,   // 显示组合关系
	ShowImplementations: true,   // 显示实现关系
	AggregatePrivate:    false, // 不聚合私有成员
})

2. 过滤特定类型

// 创建过滤器
filter := parser.NewFilter()
filter.AddIncludePattern("*Service")  // 只包含以Service结尾的类型
filter.AddExcludePattern("*test*")    // 排除包含test的类型

p := parser.NewParserWithFilter(filter)

3. 生成接口关系图

// 专注于接口和实现关系
r := renderer.NewPlantUMLRendererWithOptions(renderer.Options{
	ShowStructFields:   false,
	ShowMethods:        false,
	ShowInterfaces:      true,
	ShowImplementations: true,
})

输出示例

生成的PlantUML代码示例:

@startuml

class "example.User" {
  +ID int
  +Name string
  +Email string
  +GetProfile() *Profile
}

class "example.Profile" {
  +UserID int
  +Bio string
}

interface "example.AuthService" {
  +Login(username, password string) (string, error)
  +Logout(token string) error
}

"example.User" --> "example.Profile"
"example.UserService" ..|> "example.AuthService"

@enduml

集成到开发流程

1. 作为go generate工具

在代码中添加:

//go:generate go run github.com/jfeliu007/goplantuml/cmd/goplantuml -recursive -output docs/uml.puml

然后运行:

go generate ./...

2. 作为CI/CD的一部分

在构建脚本中添加:

goplantuml -recursive -output docs/architecture.puml

命令行工具

GoPlantUML还提供了命令行工具:

# 安装命令行工具
go install github.com/jfeliu007/goplantuml/cmd/goplantuml@latest

# 使用示例
goplantuml -recursive -output uml.puml ./src

常用参数:

  • -recursive 递归解析目录
  • -output 指定输出文件
  • -exclude 排除特定目录
  • -show-fields 显示字段
  • -show-methods 显示方法

可视化工具链

生成.puml文件后,可以使用以下工具可视化:

  1. 使用PlantUML官方工具渲染
  2. 使用VS Code的PlantUML插件实时预览
  3. 集成到文档系统如GitLab/GitHub Wiki

总结

GoPlantUML是一个强大的工具,能够自动从Go代码生成UML图表,帮助开发者:

  • 可视化项目架构
  • 理解代码关系
  • 生成项目文档
  • 进行架构评审

通过简单的集成,可以将其作为开发流程的一部分,保持文档与代码同步。

回到顶部