为什么Java将包访问设置为默认值



我之所以问这个问题,是因为我相信他们这样做是有充分理由的,而且大多数人都没有正确使用它,从我迄今为止的行业经验来看。但如果我的理论是真的,那么我不确定他们为什么包括私有访问修饰符。。。?

我相信,如果正确使用默认访问,它将在保持封装的同时提供增强的可测试性。它还使私有访问修饰符变得多余。

默认访问修饰符可以通过为需要对世界其他地方隐藏的方法使用唯一的包来提供相同的效果,并且它在不影响可测试性的情况下做到这一点,因为测试文件夹中的包可以访问源文件夹中声明的所有默认方法。

我相信这就是Java使用包访问作为"默认"的原因。但我不确定为什么它们还包括私人访问,我相信有一个有效的用例。。。

我同意对测试要访问的内容使用默认的(package private)修饰符,但我不同意private是不必要的。即使是测试,也有很多东西是不需要可见的。

对于一个好的测试,实现细节是不必要的,并且不应该在类之外可见。测试越是"白盒",它就越脆弱。我通常将默认修饰符限制在我希望通过依赖注入设置的字段中,并在测试中手动设置。(我也可以使用构造函数注入并消除它,但这更方便。)

我建议进行一些思考实验。考虑这个代码:

public void promoteUser(User user)
{
    int newRank = computeNew(user);
    user.setRank(newRank);
}
private int computeNewRank(User user)
{
    return user.getRank() + 1;
}

人们可能会觉得computeNewRank应该进行测试(真正的实现可能会做更多的事情)。但让我们暂时忘记这一点,并通过内联的魔力做到这一点:

public void promoteUser(User user)
{
    int newRank = user.getRank() + 1;
    user.setRank(newRank);
}

这个实验的美妙之处在于它适用于任何规模的私人方法。您可以想象自己内联私有成员,并问自己"我真正想在这里测试什么?"。是私有方法本身,还是伪装成私有方法的具有全新功能的新类/组件?关键是,您应该很少(如果有的话!)需要测试私有(甚至包/内部)成员。对外界来说,对你们的合同消费者来说,这些都是无关紧要的细节。

现在,我们当然可以用系统测试来代替一切。但是你的日常工作流程会是什么样子呢?如果为了测试排名晋升代码,你必须登录用户,注册会话,等待3分钟,输入晋升代码,接收短信,确认。。。你明白我的意思了。

最好记住,单元测试是为你准备的,而不是相反。你可以弯曲它们,调整它们,使它们适合,这样你就可以提供质量更好的软件。盗贼的目的不是帮助你实现100%覆盖的神奇目标,而是立即向你反馈你正在做的事情,这样你就可以更快地对遇到的错误和失败做出反应。或者换句话说,提高您的生产力

最新更新