2

In Clean Code, Robert C. Martin states that no parameter methods are better than those with very few parameters. I'm kind of confused as no parameter methods are usually harder to unit test and tend to be more coupled.

I think his rational is that since a class should only fulfill one very specific task the coupling is alright but what about unit testing?

Also the approach towards atomic methods would favor reuse of the methods so why would you try to couple them to instance methods preferably?

22
  • 2
    Can you give an example of how, in your experience, methods with no parameters tend to be more coupled and harder to unit test. Commented Oct 17, 2017 at 9:10
  • 3
    author explains in details why they think this way about testability, is there anything unclear in their reasoning? "Imagine the difficulty of writing all the test cases to ensure that all the various combinations of arguments work properly. If there are no arguments, this is trivial. If there’s one argument, it’s not too hard. With two arguments the problem gets a bit more challenging. With more than two arguments, testing every combination of appropriate values can be daunting..."
    – gnat
    Commented Oct 17, 2017 at 9:19
  • 3
    @BartvanIngenSchenau, a method with no parameters either does nothing, or it is impure, eg it is coupled to some state and so is clearly more coupled. However, it doesn't necessarily follow that such methods are harder to test, they just require more ceremony in setting up that state prior to calling the method.
    – David Arno
    Commented Oct 17, 2017 at 9:22
  • 4
    @DavidArno I re-checked the book and it doesn't look non-sequitur. Further in the discussed paragraph author makes it totally clear that they accept cases when parameters are indeed necessary. My understanding of the reasoning I quoted is one needs to avoid introducing parameters when these aren't really needed (example that immediately springs to mind is when instance variable can/should be used instead of parameter)
    – gnat
    Commented Oct 17, 2017 at 9:37
  • 3
    " However, it doesn't necessarily follow that such methods are harder to test, they just require more ceremony in setting up that state prior to calling the method. " Isn't "requires more ceremony" the same as "harder"? Commented Oct 18, 2017 at 8:45

3 Answers 3

7

My understanding of Uncle Bobs claim is: think carefully about the life cycle of your objects.

I for my self found that quite often I can turn some of the method parameters into constructor parameters since they do not change during the use of the object.

In contrast to Uncle Bobs I don't find no parameter methods superior. That is because my methods often create a return value that is used in the next method. Adding that return value to the objects state instead of passing it as parameter to the next method decreases readability because it hides a dependency between those methods. This also becomes a problem when you apply your IDEs automated refactoring move method which makes the (temporary) member variable accessible for the object the method moved to...

Also it opens the possibility to change the order of method in a wrong way. The "no state" version would throw a compiler error in such case...

2
  • 2
    A good rule of thumb is to pass only parameters used specifically in that method. Object members should have an impact across almost all public methods. It would be silly to force yourself to pass no parameters to methods just as it would be silly to force yourself to pass all parameters in every single call.
    – Neil
    Commented Oct 18, 2017 at 8:50
  • I think OP is misunderstanding the book. He never recommends passing return values as state inside the calling object instead of explicit return, he recommends combining cohesive state so that you end up with a single object and not 3 different variables. Its literally just applying SOLID principles, not anything more than that. Uncle Bob isn't claiming that all no parameter methods are better, but a cohesive class with no parameter methods is better than a class with methods that contain parameters that might as well be class members.
    – Krupip
    Commented Oct 18, 2017 at 17:01
7

The advice of Uncle Bob should be taken with a large grain of salt. It is always important to understand the context for advice and the trade-offs involved.

Bob is a proponent of the object-oriented paradigm. The underlying premise is you want to follow the OO paradigm. If you prefer a functional style or some pragmatic middle ground, his advice might not be for you.

If I understand you correctly you prefer to test methods individually. This is much simpler if there is less reliance on object state, and more on parameters. Pure side-effect free functions are especially easy to test. But this is functional style. In OO style, the "unit" is the object, not the method. You don't test a single method in isolation, you always test the behavior of an object.

When you say methods with fewer parameters are more coupled, I assume you mean more coupled to the state of the object and other methods on the same object? This is not necessarily a bad thing in OO - rather you try to achieve low coupling between objects and high cohesion for the object.

I don't think anybody have proven one paradigm to be superior to another, so this all comes down to opinion (or religion). But if you accept the premise that you want to strive for a pure OO architecture, then the advice of Bob makes sense.

1
  • 1
    "Uncle Bob" is a proponent of his own ideas, more than object oriented programming in general. Commented Oct 18, 2017 at 17:31
3

In Uncle Bob's coding style, there are many small methods with descriptive names that take no parameter but are just there to structure the code for the reader. You will usually not unit-test these methods directly, but through higher-level methods of a class. Do not make the mistake to think that you have to have a corresponding test method for each method in the class under test.

Secondly, as correctly stated in the comments, methods with no parameters still know all about the internal state of the class, they have the impleicit this parameter. Testing a method's behavior thus depends on the parameters and the state of the surrounding object. If you have no parameters, that is actually less state to think about when testing a method. I you call a method from a test, you configure it by changing the object's state. Were there parameters, this would be an even larger state space for your tests to cover, so technically you could say having zero arguments is the best case.

That said, in the end it still depends on your actual code whether it is easy to test. Say you have a function f(int a) with one parameter. You could always make int a a field of the class and the function f() now has zero parameters. This would not make it easier or harder to test.

Not the answer you're looking for? Browse other questions tagged or ask your own question.