You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

询问实例化持有对象并执行信息方法的设计模式名称

设计模式名称询问:持有对象并提供信息类方法的模式

请问是否存在这样一种设计模式的标准名称:实例化一个持有另一个对象的实例,并通过该实例对被持有的对象执行信息类方法?


基础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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 23:18:26