-4

I have one function that is used to compute distances of an object in 3 different ways.

Is one of the following two methods considered better practice:

  1. Creating 3 different functions, one each for calculating a type of distance

  2. Creating one single function with multiple if-else statements?

I am using python, and have observed a number of libraries using a 'mode' parameter in order to allow for similar kinds of functionality but with different calculations, for example the convolution function in scipy: https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.convolve2d.html. Here, the operation being done is always convolution, but the mode determines the type of convolution.

3
  • 1
    How are you calculating the distances differently? What makes you choose one of the ways over another? Apr 30, 2019 at 1:55
  • 3
    I am sure variants of this question have been asked a hundred times on this site - just can't find a real duplicate immediately. However, I don't think this is a good question, because these kind of things should be discussed in terms of examples. So my recommendation: post the source code of the function in stake on codereview.stackexchange, then you will get way better answers.
    – Doc Brown
    Apr 30, 2019 at 5:36
  • @GregBurghardt In one type of distance, the coordinates of the destination do not need to be passed, while in both the other types, they do need to be. As a result, the function signature is different for both kinds.
    – rahs
    Apr 30, 2019 at 13:56

4 Answers 4

6

Generally the first - if you find yourself writing lots of if-else statements then you'll probably soon find it hard to follow as you extend. In the second case you can have the first anyway - if presumably some other parameter is modifying your program flow through the if-else tree then you could just call another function to perform the action in that case anyway. If you do that you may find yourself asking why you need what is essentially a wrapping function.

It would depend - if these are 3 independent functions that really have nothing to do with each other but all happen to perform a similar task then there seems no reason they should be written in a single function - but it's not clear whether or not that is the case from what you state.

2

It is best not to join two or more even slightly different things together, if you can reasonably keep them apart.  The reason goes to the client consumption of our abstractions and that the different things tend to have different use cases — so we shouldn't make them all try to appear the same even if underlying computations/internals are shared, but rather cater to the separate use cases directly.  When it comes to code maintenance and refactoring, it is much better to have these categories of use cases teased apart rather than conflated into one.

0

What cyborg and Erik say. However, if ComputeDistance is the task and the different ways to go about it are just different means or contexts to the same end, you may be better served by a switch/case statement. Your code will be separated just the same and the cohesion will be preserved. You can declare an enum to name and identify the different ways of calculating and pass it as an argument. Your interface will be more stable as more different ways of calculation emerge and isolation of calculation specific logic will remain an option without breaking the interface.

This question will map to SRP in the minds of most developers but how to implement that in terms of methods really depends on what you want your code to express. Having three nicely separated methods of which it is unclear that they are related is not the best way, you do not want to lose your model in the effort of separating things.

0

I always go with single-task over multiple. It gets confusing when a function has a name that describes a single task or a bundle of tasks, but then it does more or less than advertised. If I ever feel the need to add extra functionality, that's a function of its own. Same thing with classes (my classes have a set of inter-related records, and functionalities which make sense as part of a bundle - especially for representations of real world objects).

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