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

复用对象创建新对象以使用点符号特性是否为良好实践?

通过复用对象属性创建新对象是否属于良好实践?

嗨,这个问题问得特别接地气!其实这种基于已有对象复用通用属性、仅修改差异属性来创建新对象的做法,在绝大多数场景下都是非常实用的良好实践,但得结合语言特性和具体场景来灵活处理,避免踩坑。

先看看你给出的代码例子:三个Tip实例里,body、sourceName、sourceURL这些属性完全重复,每次都从头写一遍不仅冗余,后期维护也头疼——哪天sourceName要改,你得挨个修改三个实例,很容易漏改出错。

为什么这种复用方式是好实践?

  • 减少重复代码:把通用属性抽成基础模板,只关注差异部分,代码可读性瞬间提升
  • 降低维护成本:通用属性只需要在模板里改一次,所有基于模板创建的对象都会同步受益
  • 逻辑更清晰:用点符号修改特定属性,一眼就能看出新对象和模板的差异点

具体怎么实现更优雅?

情况1:如果Tip是值类型(比如Swift结构体)

值类型赋值时会自动拷贝整个对象,修改新对象不会影响原模板,直接复用就很安全:

// 先定义一个包含通用属性的基础模板
let baseGymTip = Tip(
    title: "", 
    body: "body text, yada, yada, yada.", 
    sourceName: "SourceName", 
    sourceURL: "www.test.com", 
    sponsorLogo: "TBD", 
    sponsorURL: "www.test.com"
)

// 基于模板创建新对象,仅修改差异属性
var tipAM1 = baseGymTip
tipAM1.title = "Gym 1 Title"

var tipAM2 = baseGymTip
tipAM2.title = "Gym 2 Title"

var tipAM3 = baseGymTip
tipAM3.title = "Gym 3 Title"

情况2:如果Tip是引用类型(比如Swift类)

直接赋值会让多个变量指向同一个内存对象,修改新对象会意外改变原模板和其他实例的属性,这时候建议给类封装一个「拷贝并修改」的方法:

class Tip {
    let title: String
    let body: String
    let sourceName: String
    let sourceURL: String
    let sponsorLogo: String
    let sponsorURL: String
    
    init(title: String, body: String, sourceName: String, sourceURL: String, sponsorLogo: String, sponsorURL: String) {
        self.title = title
        self.body = body
        self.sourceName = sourceName
        self.sourceURL = sourceURL
        self.sponsorLogo = sponsorLogo
        self.sponsorURL = sponsorURL
    }
    
    // 封装一个方法,基于当前对象创建新实例,允许修改指定属性
    func with(title: String? = nil, body: String? = nil) -> Tip {
        return Tip(
            title: title ?? self.title,
            body: body ?? self.body,
            sourceName: self.sourceName,
            sourceURL: self.sourceURL,
            sponsorLogo: self.sponsorLogo,
            sponsorURL: self.sponsorURL
        )
    }
}

// 使用方式简洁又安全:
let baseGymTip = Tip(
    title: "", 
    body: "body text, yada, yada, yada.", 
    sourceName: "SourceName", 
    sourceURL: "www.test.com", 
    sponsorLogo: "TBD", 
    sponsorURL: "www.test.com"
)

let tipAM1 = baseGymTip.with(title: "Gym 1 Title")
let tipAM2 = baseGymTip.with(title: "Gym 2 Title")
let tipAM3 = baseGymTip.with(title: "Gym 3 Title")

什么时候需要谨慎使用?

  • 如果每个新对象的属性差异很大,复用模板反而会让代码逻辑变模糊,不如直接创建新实例
  • 对于完全不可变的对象(比如所有属性都是let的类),直接修改属性是不允许的,必须用「拷贝并修改」的方式

内容的提问来源于stack exchange,提问作者ajenson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:18:20