创建一个文件options.go
// 意图:通过修改选项,创建出功能不同的实例
// 解决:由于go语言没有默认值,继承,多态,所有使用选项模式来达到默认值,多态的效果
package options
import "fmt"
// 士兵
type Soldier struct {
arms string // 兵种
attack int // 攻击力
defense int // 防御力
damageRange int // 伤害范围
}
func (s *Soldier) String() string {
return fmt.Sprintf("成功创建一位%s,攻击:%d,防御:%d,伤害范围:%d", s.arms, s.attack, s.defense, s.damageRange)
}
const (
defaultAttack = 10
defaultDefense = 10
defaultDamageRange = 1
)
type options struct {
attack int
defense int
damageRange int
}
type Option interface {
apply(*options)
}
type optionFunc func(*options)
func (f optionFunc) apply(o *options) {
f(o)
}
func WithAttack(attack int) Option {
return optionFunc(func(o *options) {
o.attack = attack
})
}
func WithDefense(defense int) Option {
return optionFunc(func(o *options) {
o.defense = defense
})
}
func WithDamageRange(damageRange int) Option {
return optionFunc(func(o *options) {
o.damageRange = damageRange
})
}
// 创建一个士兵
func NewSoldier(arms string, opts ...Option) (*Soldier, error) {
// 设置默认选项
options := options{
attack: defaultAttack,
defense: defaultDefense,
damageRange: defaultDamageRange,
}
// 使用自定义选项覆盖默认选项
for _, o := range opts {
o.apply(&options)
}
return &Soldier{
arms: arms,
attack: options.attack,
defense: options.defense,
damageRange: options.damageRange,
}, nil
}
单元测试options_test.go
package options
import (
"fmt"
"testing"
)
func TestNewSoldier(t *testing.T) {
options := []Option{
WithAttack(10),
WithDefense(5),
WithDamageRange(5),
}
c, err := NewSoldier("弓箭手", options...)
if err != nil {
fmt.Println("err", err)
}
fmt.Println(c)
}
执行go test
成功创建一位弓箭手,攻击:10,防御:5,伤害范围:5
PASS
ok opeions 0.006s