什么时候对我想分享的东西在构造函数中使用静态传递引用?

When to use static over passing reference in constructor for things I want to share?

一个主题不太清楚我会尝试用一个简单的例子来解释我的问题。我们知道银行的所有客户分享银行的资金。因此,如果银行破产,则没有客户可以贷款。基于这个观点我会尝试做一个简单的程序。

方法一:

    class Client {
        private static int sharedMoney = 100;
        void takeLoan(int amount) {
            sharedMoney = sharedMoney - amount;
        }
     }

方法二:

class Client {
    private SharedMoney sharedMoney;

    public Client(SharedMoney sharedMoney) {
        this.sharedMoney = sharedMoney;
    }

    void takeLoan(int amount) {
        sharedMoney.setAmount(sharedMoney.getAmount() - amount);
    }
}

class SharedMoney {
    private int amount;

    public SharedMoney(int amount) {
        this.amount = amount;
    }

    public int getAmount() {
        return amount;
    }

    public void setAmount(int amount) {
        this.amount = amount;
    }
}

当然,逻辑不是 100% 涵盖的,但我想我表达了我的观点。有没有人有我在编码时应该遵循的经验法则?什么时候共享东西(钱)时应该使用静态,什么时候再次共享相同的东西(钱)时应该在构造函数中传递引用?

在几乎所有情况下,方法 2 都是首选。与方法 1 相比,这具有许多显着优势:

  • 测试方法 2 更容易。您可以传入一个模拟的 SharedMoney,它的行为完全符合您的测试要求(例如有特定金额)。
  • 它允许您向 SharedMoney class 添加与这些对象相关的方法,而不是在 Client 中添加与这些对象无关的静态方法class的责任
  • 静态变量包含全局状态。全局状态是可能可供任何代码访问或更改的任何程序状态。任何时候你有全局状态,你都会引入一个不相关的方法改变状态的可能性,并产生意想不到的副作用,这使得代码不可预测并且容易出现难以检测的错误。尽可能避免全局状态。替代方案通常是依赖注入,您的方法 2 就是一个很好的例子。

这些主题在 Why are static variables considered evil? 的答案中有一定的讨论,但是请注意,在很多讨论中,实际上都是关于可变静态变量的。常量值(通常声明为 private static final,并且按照惯例,给定大写名称)没有相同的缺点,因为它们的值可以依赖于不会改变。