知道却做不到

这种“知道步骤但写不出来”的情况非常常见,核心原因是对“类的参数设计”和“类之间的协作关系”还没有形成清晰的逻辑链。其实参数设计有明确的规律——每个类的参数都应该服务于它的“核心职责”。我们用“从职责倒推参数”的方法,一步步帮你落地这两个类的设计。

第一步:明确每个类的“核心职责”(先想清楚“它要干什么”)

在这个场景中:

  1. Account的核心职责:
    管理账户余额的变动(存款),并保证多线程操作时的安全性。
    → 通俗说:“它是个银行账户,要能存钱、能查余额,还得防着多人同时瞎改余额”。

  2. AddMoneyThread的核心职责:
    作为线程,执行“给指定账户存指定金额”的任务。
    → 通俗说:“它是个办事员,要知道去哪个银行账户(Account)存多少钱(金额)”。

第二步:从职责倒推每个类需要的参数(再想“需要什么才能完成职责”)

参数的本质是“类完成职责所必需的外部信息”,缺了这些信息,类就无法工作。

1. Account 类需要哪些参数?

它的职责是“管理余额+保证安全”,需要的信息:

  • 初始余额:账户刚创建时,余额是多少?(比如默认0元,但也可以让用户指定)。
    → 所以 __init__ 方法可以加一个可选参数 initial_balance,默认值0。
  • 线程锁:为了多线程安全,需要内置一个锁(这个是类内部自己创建的,不需要外部传入,所以不算参数)。

因此 Account 类的参数设计:

class Account:
    def __init__(self, initial_balance=0):  # 可选参数:初始余额,默认0
        self._balance = initial_balance  # 用初始余额初始化
        self._lock = threading.Lock()  # 内部创建锁,不用外部传

它的方法(deposit)需要什么参数?
deposit 的职责是“存多少钱”,所以必须知道“存入金额”:

def deposit(self, money):  # 必需参数:要存入的金额
    self._lock.acquire()
    try:
        self._balance += money
    finally:
        self._lock.release()

2. AddMoneyThread 类需要哪些参数?

它的职责是“作为线程给指定账户存指定金额”,需要的信息:

  • 要操作的账户:必须知道是给哪个 Account 实例存钱(没有账户,存哪里?)。
  • 要存的金额:必须知道每次存多少钱(没有金额,存多少?)。

这两个信息都需要外部提供(线程自己无法生成),所以必须作为参数传入 __init__ 方法。

因此 AddMoneyThread 类的参数设计:

class AddMoneyThread(Thread):
    def __init__(self, account, money):  # 两个必需参数:账户实例、存入金额
        super().__init__()  # 必须调用父类Thread的初始化
        self._account = account  # 保存账户实例(后面要用它调用deposit)
        self._money = money  # 保存存入金额(后面要传给deposit)

它的 run 方法需要参数吗?
不需要。因为 run 是线程启动后自动执行的,它的逻辑是固定的:“用保存的账户和金额,调用 deposit 方法”:

def run(self):
    self._account.deposit(self._money)  # 直接用实例属性,不用额外传参

第三步:主函数如何调用?(把类串联起来)

主函数的任务是“创建100个线程给同一个账户各存1元”,步骤:

  1. 创建一个 Account 实例(用默认初始余额0)。
  2. 循环100次,每次创建 AddMoneyThread 实例时,传入:
    • 同一个 Account 实例(所有线程操作同一个账户);
    • 金额1(每次存1元)。
  3. 启动所有线程,等待全部完成后,打印余额。

完整代码:

关键规律:参数设计的“必要性原则”

判断一个参数是否需要存在,就问自己:
“没有这个参数,这个类还能完成它的核心职责吗?”

  • Account 类没有 initial_balance 可以(用默认0),但 deposit 没有 money 就不行(不知道存多少)。
  • AddMoneyThread 类没有 account 不行(不知道存到哪),没有 money 也不行(不知道存多少)。

按照这个原则,你就能清晰地确定每个类需要哪些参数了。刚开始写不出来很正常,多按照“职责→参数→方法”的逻辑链练习几次,很快就能掌握这种设计思路。

posted @ 2025-10-06 20:39  java同学!  阅读(10)  评论(0)    收藏  举报