2.6 createCmd中的builder建造者设计模式
本节重点总结 :
- 设计模式之建造者模式
- 优点
- 缺点
- kubectl 中的创建者模式
设计模式之建造者模式
- 建造者(Builder)模式:指将一个复杂对象的构造与它的表示分离
- 使同样的构建过程可以创建不同的对象,这样的设计模式被称为建造者模式
- 它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成
- 它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
- 更多用来 针对复杂对象的创建
优点
- 封装性好,构建和表示分离。
- 扩展性好,各个具体的建造者相互独立,有利于系统的解耦。
- 客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险。
缺点:
- 产品的组成部分必须相同,这限制了其使用范围。
- 如果产品的内部变化复杂,如果产品内部发生变化,则建造者也要同步修改,后期维护成本较大。
kubectl 中的创建者模式
- kubectl中的 Builder对象
特点1 针对复杂对象的创建,字段非常多
-
kubectl中的 Builder对象,可以看到字段非常多
-
如果使用Init函数构造参数会非常多
-
而且参数是不固定的,即可以根据用户传入的参数情况构造不同对象
-
位置 D:\go_path\src\github.com\kubernetes\kubernetes\staging\src\k8s.io\cli-runtime\pkg\resource\builder.go
type Builder struct {
categoryExpanderFn CategoryExpanderFunc
// mapper is set explicitly by resource builders
mapper *mapper
// clientConfigFn is a function to produce a client, *if* you need one
clientConfigFn ClientConfigFunc
restMapperFn RESTMapperFunc
// objectTyper is statically determinant per-command invocation based on your internal or unstructured choice
// it does not ever need to rely upon discovery.
objectTyper runtime.ObjectTyper
// codecFactory describes which codecs you want to use
negotiatedSerializer runtime.NegotiatedSerializer
// local indicates that we cannot make server calls
local bool
errs []error
paths []Visitor
stream bool
stdinInUse bool
dir bool
labelSelector *string
fieldSelector *string
selectAll bool
limitChunks int64
requestTransforms []RequestTransform
resources []string
namespace string
allNamespace bool
names []string
resourceTuples []resourceTuple
defaultNamespace bool
requireNamespace bool
flatten bool
latest bool
requireObject bool
singleResourceType bool
continueOnError bool
singleItemImplied bool
schema ContentValidator
// fakeClientFn is used for testing
fakeClientFn FakeClientFunc
}
特点2 开头的方法返回要创建对象的指针
func NewBuilder(restClientGetter RESTClientGetter) *Builder {
categoryExpanderFn := func() (restmapper.CategoryExpander, error) {
discoveryClient, err := restClientGetter.ToDiscoveryClient()
if err != nil {
return nil, err
}
return restmapper.NewDiscoveryCategoryExpander(discoveryClient), err
}
return newBuilder(
restClientGetter.ToRESTConfig,
(&cachingRESTMapperFunc{delegate: restClientGetter.ToRESTMapper}).ToRESTMapper,
(&cachingCategoryExpanderFunc{delegate: categoryExpanderFn}).ToCategoryExpander,
)
}
特点3 所有的方法都返回的是建造对象的指针
- k8s.io\kubectl\pkg\cmd\create\create.go
r := f.NewBuilder().
Unstructured().
Schema(schema).
ContinueOnError().
NamespaceParam(cmdNamespace).DefaultNamespace().
FilenameParam(enforceNamespace, &o.FilenameOptions).
LabelSelectorParam(o.Selector).
Flatten().
Do()
- 调用时看着像链式调用,链上的每个方法都返回这个要建造对象的指针
- 如
func (b *Builder) Schema(schema ContentValidator) *Builder {
b.schema = schema
return b
}
func (b *Builder) ContinueOnError() *Builder {
b.continueOnError = true
return b
}
- 看起来就是设置构造对象的各种属性