【问题标题】:Using TDD approach and avoiding Java static methods使用 TDD 方法并避免使用 Java 静态方法
【发布时间】:2013-02-20 17:29:38
【问题描述】:

我刚收到一些关于求职申请 Java 编码练习的反馈。他们不喜欢反馈中所述的解决方案和两个问题(我非常感谢,因为很少得到反馈):

  • 显然,我没有使用 TDD 方法。
  • 我过度使用了静态方法,我知道静态方法是反 OO 的,但我只在验证和 util 类型的方法中使用它们。

这里有两个问题:

不使用 TDD 方法的可能迹象是什么?

什么编码风格或模式可以替代静态方法?

在前两个回答之后,我还有一个问题。

您是否同意使用静态方法只有在限制代码的可测试性而不是它们本身不好时才是不好的。

如果静态方法不限制我的代码的可测试性,那么回到我的工作申请练习解决方案,使用它仍然不好吗?我的验证方法非常简单 'Validator.notNull(p,"paramName")' 现在我为什么要模拟它?

非常感谢。

【问题讨论】:

    标签: methods static tdd


    【解决方案1】:

    不使用 TDD 的一个明显标志是协作者使用静态方法和静态类成员。您不能覆盖静态方法,因此不能单独使用此类方法替换模拟来测试类。

    您可以使用依赖注入,而不是使用静态协作者或协作者上的静态方法。在一个简单的编码练习中,您将通过构造函数或手动通过 setter 注入依赖项。在现实生活中,您可以使用其中一种可用的依赖框架。

    【讨论】:

    • 感谢奥拉夫,所以如果我有 someBizObj.someBusinessMethod(SomeParam param);在这个方法中我调用 Validation.notNull(param,"pramName");根据您的建议,您将如何更改?
    • +1 回答。 @Ramo 请参阅下面的答案以获取一个简单的示例。希望有帮助
    【解决方案2】:

    您的静态 Validaton 方法对我来说似乎应该是对象的一部分。

    假设你有一个班级Drink

    public class Drink
    {
        private readonly string _name;
        private readonly double _temperature;
    
        public Drink(string name, double temperature)
        {
            _name = name;
            _temperature = temperature;
        }
    }
    

    您的业务逻辑将能够实例化各种饮料、7up、可乐等。您想确保饮料具有合适的饮用温度,因此您需要Validate 方法。你可以按照你的方法:

    public void TakeAZip()
    {
        if (Validation.HasAppropriateTemp)
        {
            // implement drink
        }
    }
    

    '

    静态类的替代方案

    这样你就很难依赖你的静态 Validation 类。

    您也可以使用dependency injection

    public void TakeAZip(ITemperatureValidator validator)
    {
        if (validator.HasAppropriateTemp)
        {
            // implement drink
        }
    }
    

    如果更方便,您还可以选择通过构造函数传递Validator

        private readonly string _name;
        private readonly double _temperature;
        private ITemperatureValidator _validator;
    
        public Drink(
            string name, 
            double temperature, 
            ITemperatureValidator validator)
        {
            _name = name;
            _temperature = temperature;
            _validator = validator;
        }
    

    现在您可以mock 验证器的行为,并且可以将您的Drink 类与所有外部行为隔离开来。

    【讨论】:

    • 非常感谢@bas,因此验证器可以实现为单例并根据需要传递,并且在测试时我们只模拟验证器接口并注入模拟。
    • @Ramo 嗯,你必须用那个词吗... :)。单身人士不是你最好的朋友。如果您正在寻找一个与 Singletons 相关的故事。阅读此线程作为参考stackoverflow.com/questions/5486562/…
    猜你喜欢
    • 2014-12-19
    • 1970-01-01
    • 1970-01-01
    • 2017-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-17
    • 2015-12-21
    相关资源
    最近更新 更多