This article has an English version available.
对象中成员变量的角色
下面用一个典型的类定义来展示成员变量的不同角色:
python
class Parent:
# 配置
feature_a_flag: bool
# 借用资源
"""这是一个用于发起 HTTP 请求的客户端。
它在全局初始化,
并在程序中被所有对象共享。"""
client: Client
# 自有资源
"""这是一个数据库连接。
我们需要调用 `connect()` 才能开始使用它。
用完之后需要调用 `close()`。"""
conn: Connection
# 状态
last_modified_time: float
# 子对象
child: List[Child]配置(Config)
配置相对简单。它通常是原始值,比如字符串、数字、布尔值等,或是由原始值组成的结构(例如 JSON 风格的对象)。
配置是只读的,运行时不会改变,通常在构造函数中初始化。
由于它是只读的,所以可以安全地在对象之间共享,比如传给其他对象的构造函数。
而且由于它是原始值,我们不用担心内存管理问题,直接传递给 GC 处理即可。
借用资源(Borrowed resources)
借用资源通常在多个对象之间共享。它可能在全局初始化后被所有对象共享,也可能在某个对象中初始化后被其他对象借用。
当一个对象从另一个对象借用资源时,它并不拥有该资源,因此不需要调用 close() 来销毁它。
但是它必须确保自己使用该资源时该资源仍然可用,也就是说它的生命周期必须在资源拥有者的生命周期之内。拥有者必须在借用者存活期间保持存活,而借用者必须在拥有者销毁之前被销毁。
自有资源(Owned resources)
如前所述,拥有资源意味着对象要对资源的生命周期负责,需要调用 close() 来销毁它。
状态(States)
“状态”可以包含构成对象的一切信息,但这里我们将其定义为自有资源的一个子集:它由对象拥有,且不与其他对象共享。
状态只服务于对象本身,并且会被对象的方法频繁修改。相比之下,配置与资源通常在构造函数中设置,并在之后很少改变。
即便我们调用资源的可变方法,也是在改变资源自身的状态,而不是对象本身的状态。
你可能会注意到,自有资源的状态也是对象状态的一种。但为了清晰起见,我们仍把它们分开,这是“子状态”。
子对象(Children objects)
子对象也可以被视为一种自有资源或状态。父对象需要负责它们的生命周期。
子对象可以拥有自己的状态,而这些状态如上所述是父对象的子状态。
子对象可以拥有自己的资源,也可以从父对象借用资源。这很自然,因为它的生命周期由父对象管理,因此天然处于父对象生命周期之内。