询问实例化持有对象并执行信息方法的设计模式名称
设计模式名称询问:持有对象并提供信息类方法的模式
请问是否存在这样一种设计模式的标准名称:实例化一个持有另一个对象的实例,并通过该实例对被持有的对象执行信息类方法?
基础Go语言示例代码
type Foo struct { prop1 string prop2 string prop3 bool } type Bar struct { foo Foo } func (b Bar) info1() bool { return b.foo.prop1 == b.foo.prop2 } func (b Bar) info2() (string, string) { split1 := strings.Split(b.foo.prop1, "sep1") split2 := strings.Split(b.foo.prop2, "sep2") return strings.Join(split1, "newsep1"), strings.Join(split2, "newsep2") }
carvel kapp中的实际使用代码片段
(注:实际kapp代码中,VersionedResource并非仅用于信息类用途,此为精简后的示例)
// Copyright 2020 VMware, Inc. // SPDX-License-Identifier: Apache-2.0 // ... const ( nameSuffixSep = "-ver-" ) type VersionedResource struct { res ctlres.Resource stripNameHashSuffix bool } func (d VersionedResource) StripNameHashSuffix() bool { stripEnabled := d.stripNameHashSuffix // TODO should properly check using a ResourceMatcher matchesRequiredKind := d.res.Kind() == "ConfigMap" || d.res.Kind() == "Secret" return stripEnabled && matchesRequiredKind } // [...] func (d VersionedResource) BaseNameAndVersion() (string, string) { name := d.res.Name() pieces := strings.Split(name, nameSuffixSep) if len(pieces) > 1 { return strings.Join(pieces[0:len(pieces)-1], nameSuffixSep), pieces[len(pieces)-1] } if d.StripNameHashSuffix() { pieces = strings.Split(name, "-") if len(pieces) > 1 { return strings.Join(pieces[0:len(pieces)-1], "-"), "" } } return name, "" } func (d VersionedResource) Version() int { _, ver := d.BaseNameAndVersion() if len(ver) == 0 { if d.StripNameHashSuffix() { return -1 } panic(fmt.Sprintf("Missing version in versioned resource '%s'", d.res.Description())) } verInt, err1 := strconv.Atoi(ver) if err1 != nil { panic(fmt.Sprintf("Invalid version in versioned resource '%s'", d.res.Description())) } return verInt } func (d VersionedResource) UniqVersionedKey() ctlres.UniqueResourceKey { baseName, _ := d.BaseNameAndVersion() return ctlres.NewUniqueResourceKeyWithCustomName(d.res, baseName) } func (d VersionedResource) TrackVersions() bool { _, hasVersionedAnn := d.res.Annotations()[versionedResAnnKey] return hasVersionedAnn } func (d VersionedResource) IsVersioned() bool { if d.StripNameHashSuffix() { return true } return d.TrackVersions() } func (d VersionedResource) IsExistingVersioned() bool { // Expect that versioned resources should not be transient // (Annotations may have been copied from versioned resources // onto transient resources for non-versioning related purposes). notTransient := !d.res.Transient() // TODO check moved during refactoring, but not sure why it is required _, version := d.BaseNameAndVersion() hasVersion := version != "" versionUnnecessary := !d.TrackVersions() return d.IsVersioned() && notTransient && (hasVersion || versionUnnecessary) } // ...
使用示例代码
// Copyright 2020 VMware, Inc. // SPDX-License-Identifier: Apache-2.0 // ... func (d ChangeSetWithVersionedRs) groupResources(rs []ctlres.Resource) map[string][]ctlres.Resource { result := map[string][]ctlres.Resource{} groupByFunc := func(res ctlres.Resource) string { versionedRes := VersionedResource{res, d.stripNameHashSuffix} if versionedRes.IsVersioned() { return versionedRes.UniqVersionedKey().String() } panic("Expected to find versioned annotation on resource") } for resKey, subRs := range (GroupResources{rs, groupByFunc}).Resources() { sort.Slice(subRs, func(i, j int) bool { return d.versionedResourceName(subRs[i]).Version() < d.versionedResourceName(subRs[j]).Version() }) result[resKey] = subRs } return result } // ...
对应的设计模式名称
这种写法在实践中通常被称为包装器(Wrapper),它不属于GoF经典23种设计模式,但属于基于对象组合的常见代码组织方式。如果要归类到标准设计模式中,最接近的是外观模式(Facade)——外观模式的核心是为目标对象(或复杂系统)提供简化的接口,你的实现正是通过持有目标对象,封装了对其属性的查询、计算等信息类操作,对外提供更易用的专属接口。
如果需要动态为对象添加这类信息查询功能,**装饰器模式(Decorator)**会更贴合,但你的代码是静态持有对象并提供固定的信息方法,因此包装器/外观模式的描述更准确。
内容的提问来源于stack exchange,提问作者criztovyl
相关产品推荐
相关产品推荐

