Skip to content

Commit b7cee58

Browse files
committed
feat: add 03 builder
1 parent 63d0420 commit b7cee58

File tree

5 files changed

+255
-1
lines changed

5 files changed

+255
-1
lines changed

03_builder/builder.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package builder
2+
3+
import "fmt"
4+
5+
const (
6+
defaultMaxTotal = 10
7+
defaultMaxIdle = 9
8+
defaultMinIdle = 1
9+
)
10+
11+
// ResourcePoolConfig resource pool
12+
type ResourcePoolConfig struct {
13+
name string
14+
maxTotal int
15+
maxIdle int
16+
minIdle int
17+
}
18+
19+
// ResourcePoolConfigBuilder 用于构建 ResourcePoolConfig
20+
type ResourcePoolConfigBuilder struct {
21+
name string
22+
maxTotal int
23+
maxIdle int
24+
minIdle int
25+
}
26+
27+
// SetName SetName
28+
func (b *ResourcePoolConfigBuilder) SetName(name string) error {
29+
if name == "" {
30+
return fmt.Errorf("name can not be empty")
31+
}
32+
b.name = name
33+
return nil
34+
}
35+
36+
// SetMinIdle SetMinIdle
37+
func (b *ResourcePoolConfigBuilder) SetMinIdle(minIdle int) error {
38+
if minIdle < 0 {
39+
return fmt.Errorf("max tatal cannot < 0, input: %d", minIdle)
40+
}
41+
b.minIdle = minIdle
42+
return nil
43+
}
44+
45+
// SetMaxIdle SetMaxIdle
46+
func (b *ResourcePoolConfigBuilder) SetMaxIdle(maxIdle int) error {
47+
if maxIdle < 0 {
48+
return fmt.Errorf("max tatal cannot < 0, input: %d", maxIdle)
49+
}
50+
b.maxIdle = maxIdle
51+
return nil
52+
}
53+
54+
// SetMaxTotal SetMaxTotal
55+
func (b *ResourcePoolConfigBuilder) SetMaxTotal(maxTotal int) error {
56+
if maxTotal <= 0 {
57+
return fmt.Errorf("max tatal cannot <= 0, input: %d", maxTotal)
58+
}
59+
b.maxTotal = maxTotal
60+
return nil
61+
}
62+
63+
// Build Build
64+
func (b *ResourcePoolConfigBuilder) Build() (*ResourcePoolConfig, error) {
65+
if b.name == "" {
66+
return nil, fmt.Errorf("name can not be empty")
67+
}
68+
69+
// 设置默认值
70+
if b.minIdle == 0 {
71+
b.minIdle = defaultMinIdle
72+
}
73+
74+
if b.maxIdle == 0 {
75+
b.maxIdle = defaultMaxIdle
76+
}
77+
78+
if b.maxTotal == 0 {
79+
b.maxTotal = defaultMaxTotal
80+
}
81+
82+
if b.maxTotal < b.maxIdle {
83+
return nil, fmt.Errorf("max total(%d) cannot < max idle(%d)", b.maxTotal, b.maxIdle)
84+
}
85+
86+
if b.minIdle > b.maxIdle {
87+
return nil, fmt.Errorf("max idle(%d) cannot < min idle(%d)", b.maxIdle, b.minIdle)
88+
}
89+
90+
return &ResourcePoolConfig{
91+
name: b.name,
92+
maxTotal: b.maxTotal,
93+
maxIdle: b.maxIdle,
94+
minIdle: b.minIdle,
95+
}, nil
96+
}

03_builder/builder_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package builder
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
func TestResourcePoolConfigBuilder_Build(t *testing.T) {
11+
tests := []struct {
12+
name string
13+
builder *ResourcePoolConfigBuilder
14+
want *ResourcePoolConfig
15+
wantErr bool
16+
}{
17+
{
18+
name: "name empty",
19+
builder: &ResourcePoolConfigBuilder{
20+
name: "",
21+
maxTotal: 0,
22+
},
23+
want: nil,
24+
wantErr: true,
25+
},
26+
{
27+
name: "maxIdle < minIdle",
28+
builder: &ResourcePoolConfigBuilder{
29+
name: "test",
30+
maxTotal: 0,
31+
maxIdle: 10,
32+
minIdle: 20,
33+
},
34+
want: nil,
35+
wantErr: true,
36+
},
37+
{
38+
name: "success",
39+
builder: &ResourcePoolConfigBuilder{
40+
name: "test",
41+
},
42+
want: &ResourcePoolConfig{
43+
name: "test",
44+
maxTotal: defaultMaxTotal,
45+
maxIdle: defaultMaxIdle,
46+
minIdle: defaultMinIdle,
47+
},
48+
wantErr: false,
49+
},
50+
}
51+
for _, tt := range tests {
52+
t.Run(tt.name, func(t *testing.T) {
53+
got, err := tt.builder.Build()
54+
require.Equalf(t, tt.wantErr, err != nil, "Build() error = %v, wantErr %v", err, tt.wantErr)
55+
assert.Equal(t, tt.want, got)
56+
})
57+
}
58+
}

03_builder/option.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package builder
2+
3+
import "fmt"
4+
5+
// ResourcePoolConfigOption option
6+
type ResourcePoolConfigOption struct {
7+
maxTotal int
8+
maxIdle int
9+
minIdle int
10+
}
11+
12+
// ResourcePoolConfigOptFunc to set option
13+
type ResourcePoolConfigOptFunc func(option *ResourcePoolConfigOption)
14+
15+
// NewResourcePoolConfig NewResourcePoolConfig
16+
func NewResourcePoolConfig(name string, opts ...ResourcePoolConfigOptFunc) (*ResourcePoolConfig, error) {
17+
if name == "" {
18+
return nil, fmt.Errorf("name can not be empty")
19+
}
20+
21+
option := &ResourcePoolConfigOption{
22+
maxTotal: 10,
23+
maxIdle: 9,
24+
minIdle: 1,
25+
}
26+
27+
for _, opt := range opts {
28+
opt(option)
29+
}
30+
31+
if option.maxTotal < 0 || option.maxIdle < 0 || option.minIdle < 0 {
32+
return nil, fmt.Errorf("args err, option: %v", option)
33+
}
34+
35+
if option.maxTotal < option.maxIdle || option.minIdle > option.maxIdle {
36+
return nil, fmt.Errorf("args err, option: %v", option)
37+
}
38+
39+
return &ResourcePoolConfig{
40+
name: name,
41+
maxTotal: option.maxTotal,
42+
maxIdle: option.maxIdle,
43+
minIdle: option.minIdle,
44+
}, nil
45+
}

03_builder/option_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package builder
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
func TestNewResourcePoolConfig(t *testing.T) {
11+
type args struct {
12+
name string
13+
opts []ResourcePoolConfigOptFunc
14+
}
15+
tests := []struct {
16+
name string
17+
args args
18+
want *ResourcePoolConfig
19+
wantErr bool
20+
}{
21+
{
22+
name: "name empty",
23+
args: args{
24+
name: "",
25+
},
26+
want: nil,
27+
wantErr: true,
28+
},
29+
{
30+
name: "success",
31+
args: args{
32+
name: "test",
33+
opts: []ResourcePoolConfigOptFunc{
34+
func(option *ResourcePoolConfigOption) {
35+
option.minIdle = 2
36+
},
37+
},
38+
},
39+
want: &ResourcePoolConfig{
40+
name: "test",
41+
maxTotal: 10,
42+
maxIdle: 9,
43+
minIdle: 2,
44+
},
45+
wantErr: false,
46+
},
47+
}
48+
for _, tt := range tests {
49+
t.Run(tt.name, func(t *testing.T) {
50+
got, err := NewResourcePoolConfig(tt.args.name, tt.args.opts...)
51+
require.Equalf(t, tt.wantErr, err != nil, "error = %v, wantErr %v", err, tt.wantErr)
52+
assert.Equal(t, tt.want, got)
53+
})
54+
}
55+
}

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ go 设计模式实现,包含 23 种常见的设计模式实现
2020
- [工厂方法](./02_factory/022_factory_method)
2121
- [抽象工厂(不常用)](./02_factory/023_abstract_factory)
2222
- [DI 容器](./02_factory/024_di)
23-
- 建造者模式
23+
- [建造者模式](./03_builder) [![](https://img.shields.io/badge/BLOG-%E7%82%B9%E5%87%BB%E6%9F%A5%E7%9C%8B-success?style=flat&cacheSeconds=360000)](https://lailin.xyz/post/builder.html)
2424

2525
### 不常用
2626

0 commit comments

Comments
 (0)