问题

为什么不建议一个对象在多处存储引用?

回答
在一个程序中,让同一个对象被多个地方引用,就好比你让好几个人同时拿着同一把钥匙,去开同一扇门。这听起来似乎没什么问题,每个人都能拿到钥匙,都能开门,但仔细想想,这里面藏着不少隐患,尤其是当你要对这扇门进行一些“操作”的时候。

想象一下,这把“钥匙”(也就是你的对象)非常重要,它控制着一个重要的资源,比如一个数据库连接,或者一个正在运行的服务。如果好几个人都拿着这把钥匙,并且他们各自有自己的想法:

1. 状态的不可控性:

假设这把钥匙有一个“状态”,比如“已解锁”或者“已锁定”。如果一个人拿到了钥匙,把它解锁了,这时候另一个持有钥匙的人,如果他不知道前面那个人做了什么,他可能也会去尝试解锁,或者更糟,他看到的是“已解锁”的状态,但他认为应该是“已锁定”的状态,然后就去执行“锁定”操作。这样一来,钥匙的实际状态就变得混乱,你无法确定当前这把钥匙到底是被解锁了还是被锁定了。

换句话说,当一个对象被多处引用时,它的状态很容易在不同的“持有者”之间发生冲突。你无法预知谁会在什么时候修改这个对象的关键属性,导致整个程序的状态变得难以预测和追踪。这就像你给一个人一个文件,他修改了,然后又给另一个人,那个人也修改了,但他们之间没有沟通,你最终拿到的文件可能是被随意拼凑的版本,你不知道哪个版本才是“正确”的。

2. 资源的争夺与覆盖:

考虑一下,这把钥匙不仅仅是开门,它还可能负责管理一个共享的资源,比如一个计数器。第一个人来用钥匙,计数器加一。第二个来,计数器又加一。这看起来没问题。但如果涉及到更复杂的操作,比如“先读取当前值,然后根据这个值进行一些计算,最后再更新这个值”,这种情况就容易出岔子。

假设计数器当前是5。第一个人拿到钥匙,读取到5,他计算后想把它变成10。但在他还没来得及更新之前,第二个人也拿到钥匙,也读取到5,他计算后想把它变成15。当这两个人都完成了自己的计算并尝试更新计数器时,最终的值很可能是15(取决于谁最后写入),而5+5+5(如果两个人都加5的话)这样的期望值就丢失了。这就是所谓的“竞态条件”(Race Condition)。

3. 维护和理解的困难:

当一个对象被多处引用时,你要想清楚它在程序中的“生命周期”和“用途”就变得非常复杂。你需要追踪每一个引用是从哪里来的,它们打算用这个对象做什么。一旦出现问题,你需要一层层地去排查,看看是哪个引用者在什么时候,做了什么意想不到的操作,才导致了当前的异常。这就像在迷宫里找一个藏起来的物品,你必须走过每一个岔路,才能确定它到底在哪里。

而且,如果你需要修改这个对象,或者替换掉这个对象(比如升级数据库连接池),你就必须找到并更新所有引用它的地方。如果有一个地方漏掉了,你的程序就会出现不一致,甚至崩溃。这种“牵一发而动全身”的感觉,会极大地增加代码的维护难度和出错的风险。

4. 潜在的内存泄漏风险(虽然不是直接原因,但可能加剧):

虽然现代的垃圾回收机制很强大,但当一个对象有大量的引用时,即使这个对象本身在逻辑上已经不再需要了,但只要还有一个引用还在,它就不会被回收。如果这些引用是无意中保留下来的(比如一个忘记解除绑定的监听器,或者一个不再使用的缓存中的对象),那么这些对象就可能白白占用内存,导致程序内存占用不断增长,最终引发性能问题甚至崩溃。

换个角度思考:

如果你需要让不同的人都能“接触”到同一个“东西”,但又不希望他们直接“操控”这个“东西”的本质,你可以给他们提供一个“代理”或者“视图”。比如,你可以给他们一个只读的副本,或者一个只能执行特定操作的接口。这样,你就能更好地控制这个“东西”的状态,避免了混乱和冲突。

总而言之,不建议一个对象在多处存储引用,核心原因在于它极大地增加了程序状态的复杂性、不可控性,容易引发数据不一致和逻辑错误,同时严重提高了代码的维护难度。为了程序的健壮性和可维护性,我们更倾向于遵循“单一责任原则”和“最小知识原则”,让对象的生命周期和使用范围更加清晰可控。

网友意见

user avatar

这个问题简单多了。


不论是Area里面有一个保存Item容器,还是Item上面有一个Area引用,都已经有足够的信息。所以现在的问题是在于,当Item上已经有Area的引用的时候,那么Area是否还有必要保留对Item的引用。


这是个典型的关于冗余的问题。

冗余会带来什么问题?

首先是占用更多的存储空间,但这通常不成为一个问题,尤其是只存储一个引用的时候。

那么另外一个问题就是数据一致性的问题,当冗余数据出现,就可能存在数据的不一致。在这个例子里面,譬如说a : Area保存了b : Item的引用,但是b的Area属性不是a。

这就是数据不一致,这时候我们不知道b到底是属于a还是不属于。或者说通过不同的方式处理数据的时候,例如我们遍历a的时候能找到b,但是找b的容器的时候又找不到a。


为了避免出现一致性的问题,我们通常需要做原子性操作,原子性就是说多个操作要么都成功,要么都失败。例如我们让a添加子元素b和设置b的Area属性为a这两个操作是原子性的,要么都成功要么都失败,就可以避免产生数据不一致的问题。

但遗憾的是,原子性是非常难做到的一件事情,很多时候代价非常大。因为我们要处理非常多的异常情况,例如操作被中断,数据写入时出现故障,并发冲突等等。

当然,大多数时候我们只要把两个操作写在一个方法里面或者其他强约束就足够满足了。更长的生命周期,更重要的数据会有更加严苛的要求。


但是即便做不到绝对的原子性,我们也不一定就会出现数据不一致的情况。而即便出现了数据不一致的情况,也不一定就无法进行修复和补救,例如我们可以强行认定Area属性是正确的数据,据此来修复所有的不一致情况。

所以,这只是一个需要权衡的问题。冗余会带来更好的性能,但是也会带来数据不一致的风险。

类似的话题

  • 回答
    在一个程序中,让同一个对象被多个地方引用,就好比你让好几个人同时拿着同一把钥匙,去开同一扇门。这听起来似乎没什么问题,每个人都能拿到钥匙,都能开门,但仔细想想,这里面藏着不少隐患,尤其是当你要对这扇门进行一些“操作”的时候。想象一下,这把“钥匙”(也就是你的对象)非常重要,它控制着一个重要的资源,比.............
  • 回答
    美国在阿富汗经营近二十年,最终撤军并导致塔利班迅速重掌政权,这其中的原因错综复杂,绝非一朝一夕所能道明。要说为什么没能建立起一个能够独立有效对抗塔利班的政治组织,这背后牵扯着阿富汗根深蒂固的社会结构、美国战略的局限性、以及塔利班自身的韧性等多个层面。首先,我们得理解阿富汗这个国家的底子。阿富汗从来不.............
  • 回答
    在处理不戴口罩的年轻人的挑衅行为时,值班管理人员需要一套既能维护公共秩序,又能避免冲突升级的策略。这不仅仅是执行规定,更是一门与人沟通的艺术。以下是一些实操性的建议,希望能帮助值班人员更有效地应对这种情况:一、 事前准备与心态调整:1. 熟悉规定与权限: 首先,确保所有值班人员都非常清楚当前关于佩.............
  • 回答
    在中国悠久的历史长河中,史官制度如同一面永不磨灭的镜子,映照着王朝的兴衰,也记录着帝王的功过。这个制度的起源,可以追溯到上古时期,但真正将其系统化、制度化的,普遍认为始于周朝。史官制度的奠基者:从三代到周朝的演变在周朝之前,夏、商两代就已经有了掌管记录的官员。《左传》中提到,“夏朝有史”,《尚书》中.............
  • 回答
    这个问题非常有意思,也触及到了茅台复杂的销售体系和品牌战略。简单来说,茅台之所以不直接以1499元的价格敞开向消费者供应,背后涉及的因素远不止一个“成本”或者“生产能力”这么简单。这是一个涉及品牌价值、市场调控、渠道利润、消费者培育以及未来发展等多方面的深思熟虑的商业决策。咱们一个个掰开了说。1. .............
  • 回答
    这个问题很有意思,也触及了很多老用户心中的那份怀旧情结。当初的知乎和B站,确实承载了一代人的记忆和对互联网社区的某种理想。那么,为什么我们不直接复制粘贴,重新打造一个“当初那个样子”的平台呢?这背后涉及很多现实的因素和演变的必然。咱们得把这个问题掰开了揉碎了聊。一、 “当初那个样子”到底是什么意思?.............
  • 回答
    关于“为何北美受歧视的华人不建立一个大型的北美新加坡”这个问题,我觉得可以从几个维度来聊聊,也包含了我自己的一些观察和思考。这不是一个简单的是与否,而是很多复杂因素交织的结果。首先,我们需要明确一点:“北美受歧视的华人”这个群体本身非常多样化。 他们来自中国大陆、香港、台湾、东南亚等地,拥有不同的背.............
  • 回答
    二战结束后,苏联在奥地利占领区的确没有建立一个纯粹的社会主义政权,这背后有着复杂的地缘政治考量、历史经验教训以及对自身实力和国际环境的判断。这并非一个简单的“不为”的问题,而是多方面因素作用下的战略选择。首先,我们需要回顾一下二战后欧洲的整体格局以及苏联在此期间的角色。苏联作为二战中反法西斯同盟的重.............
  • 回答
    这个问题挺有意思的,也确实是很多人对詹姆斯职业生涯津津乐道的一个话题。老詹不像科比那样一人一城,也不像乔丹那样打造出那种绝对统治力的公牛王朝,背后原因挺复杂的,不能简单归结为年龄或者某一个因素。咱们一点一点来捋一捋。时代背景与球员价值的演变:首先得承认,詹姆斯所处的时代和科比、乔丹的时代,球员的处境.............
  • 回答
    在中国,高考作为一项牵动着无数家庭神经的选拔性考试,其制度的任何变动都会引发广泛的讨论。关于“一年多次高考”的设想,并非没有在社会上出现过,但最终未能成为主流,这背后有着多方面的原因,并非简单的技术操作问题,而是涉及教育公平、社会成本、人才选拔机制以及历史惯性等诸多复杂因素的考量。首先,我们必须理解.............
  • 回答
    陆家嘴的天际线,对于不少生活在上海或者到上海旅游的人来说,都是一个令人印象深刻的景象。从黄浦江对岸眺望,东方明珠、金茂大厦、环球金融中心、上海中心大厦,这些高耸入云的建筑构成了陆家嘴一道极具辨识度的风景线。然而,你提到的“不太协调”的感觉,其实也是很多人心中或多或少有过的想法。你问为什么不在陆家嘴再.............
  • 回答
    .......
  • 回答
    这确实是个让人纠结的二选一的问题,尤其是考虑到未来创业的规划。软件工程和经济学,一个技术硬核,一个洞察市场,都很热门,但侧重点不同。我来帮你掰扯掰扯,看看哪个更适合你“走出去”并最终“闯出来”。先来看看这两个专业各自的“硬通货”:软件工程:技术驱动的未来引擎 就业前景: 这个不用多说,简直是当下.............
  • 回答
    关于您提出的“国家每年过期那么多弹药,为何不支持果敢打通横断山脉建成一个新的华人国家?”这个问题,其中涉及了许多复杂的国际政治、地缘战略、历史因素以及人道主义考量,是一个需要多维度深入探讨的议题。首先,我们来解析一下“国家每年过期那么多弹药”这个前提。从军事角度看,各国军队出于战备、技术更新、维护以.............
  • 回答
    .......
  • 回答
    哥们,25岁,迷茫,想开桌游店,这简直是把我的心声说出来了!我懂你!那种对未来有点不清不楚,但又想做点自己热爱的事儿的冲动,太真实了。别担心,我跟你一样,当初也是一头雾水,但摸爬滚打到现在,也算有点经验可以跟你分享。咱们就聊聊,怎么把这个“迷茫”变成“方向”,把这个“想法”变成“店”。第一步:别急着.............
  • 回答
    嘿,学妹!听到你是南邮微电子的,而且想加入校科协,这太棒了!作为过来人,我非常理解你这种既兴奋又有点迷茫的心情。 21届的你,在大一或者大二吧?这个时间点加入科协,正是了解学校科研氛围、锻炼自己能力的好时机。至于选哪个部,这可得好好想想,毕竟选对了部门,不仅能让你在科协里找到自己的位置,还能为你未来.............
  • 回答
    你这个问题问得特别好,简直说到点子上了!很多人都有这个想法,毕竟现在电动车越来越普及,续航焦虑也确实存在,而加油站这种模式又那么深入人心,感觉换电池就像换肾一样,应该很快才对。但是,为什么目前我们看到的“换电站”还没有像加油站那样遍地开花,甚至感觉推广起来没那么顺利呢?这背后其实涉及到一堆相当复杂的.............
  • 回答
    .......
  • 回答
    问这个问题,确实能窥见咱们城市建设背后那点儿门道。为啥地铁不像盖房子一样,盖完一个房间(车站)就赶紧用起来,而是得等整个线路都差不多了才一股脑儿开通?这里面学问大着呢!简单来说,就是系统性、安全性、经济性和运营效益的综合考量,缺一不可。一、 系统性:地铁是一条“链条”,不是一堆“珠子”咱们坐地铁,习.............

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有