0

Sonarqube allows only 7 parameters for the function. I have a function that forms the string with 8 parameters.

fun example(
        context: Context,
        a: Int,
        b: Int,
        c: String,
        d: Int,
        e: String,
        list: List<String>,
        dat: String
) {
a = d+b
var f = a+b+d
if (list >0){
f = f+ "example"
}
return c+ e + f + dat
}

To make this function have only 7 parameters. I split the function by removing last parameter dat but in order to calculate dat variable I need b and d variables value also. So after function returns I need the value of b and d to evaluate dat and later concat dat to function return. Like below

fun example(
        context: Context,
        a: Int,
        b: Int,
        c: String,
        d: Int,
        e: String,
        list: List<String>
) {
a = d+b
var f = a+b+d
if (list >0){
f = f+ "example"
}
return c+ e + f
}

// i call it like below
example(context, 1, 1, "c", 1, "e", listOf('list1', 'list2')) + exampleConcat("dat text")

fun exampleConcat(dat: String) {
val t = d + b + dat  // here i need the latest value of 'd' and 'b'
return t
}

How do i get d and b latest value becoz after function returns these local variable will be destroyed?. How to make this function efficient by passing 7 arguments.

Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • I think a better way to do it is https://stackoverflow.com/questions/49535099/method-has-8-parameters-which-is-greater-than-7-authorized. – ADM May 10 '21 at 11:23
  • The restriction on number of parameters is because there's a possible design issue affecting code maintainability. If you solve it by making it more complicated (like hiding multiple parameters in a tuple or list), you're just making the issue worse. It would be preferable to ignore the Sonar warning than to dig a deeper hole. – Tenfour04 May 10 '21 at 13:27

2 Answers2

0

You can make a custom data model which would take multiple values.

like this

data class CustomModel(
var list:List<String>
var dat:String
)

Hence you solution will be something like this.

fun example(
        context: Context,
        a: Int,
        b: Int,
        c: String,
        d: Int,
        e: String,
        customModel:CustomModel
) {
a = d+b
var f = a+b+d
if (customModel.list >0){
f = f+ "example"
}
return c+ e + f + customModel.dat
}

Now you call your function example() and pass the CustomModel(list,dat) into your customModel param in the example function.

thebadassdev
  • 156
  • 9
0

Let's start from a question - why more than 7 parameters in a function is a bad thing?

The answer is quite simple - it's all about readability. So, what we can do about it?

1. Opts object

data class ExampleOpts(
    public val p1: String,
    ...
    public val p10: Int = 0
)

fun example(opts: ExampleOpts) {

}

This way is much more readable - the function signature suggests it has a lot of parameters, so it's a kind of good thing to extract them to its own structure.

2. Builder

When we reach such a number of parameters it may be good to somehow validate the data outside the method. We can do it using a builder. It's not common in kotlin, as a lot of pros of builder we can get using simply a data class (like default parameters etc.). However, sometimes it may be worthy, especially when we need to validate the data.

Read more about Builder Pattern in Kotlin

3. Just ignore the issue :)

In fact, we should not treat all issues in SonarQube (or any other linter) as a must-fix, because it's just a result of static analysis. Sometimes it's just a normal thing to have even more parameters. For example:

example of functions with up to 22 parameters

As we can see in this library we have even more parameters than 7 and it's totally, totally fine.

4. It's not about reducing the number of parameters, it's all about increasing the readability.

Such a number of parameters suggest that there may be something wrong with an implementation. And a quick look at the implementation suggests it is.

fun example(
        context: Context,
        a: Int,
        b: Int,
        c: String,
        d: Int,
        e: String,
        customModel: CustomModel
) {
    a = d + b
    var f = a + b + d
    if (customModel.list > 0) {
        f = f + "example"
    }
    
    return c + e + f + customModel.dat
}

context - not used

a - won't compile, because a is redeclared at the very first line (val cannot be reassigned)

So, the number of parameters is not always a problem - it's just a suggestion, that something may be wrong. It's up to you to verify it and fix it if needed.

Cililing
  • 4,303
  • 1
  • 17
  • 35
  • 1
    It's not just about readability, but also the single-responsibility principle. Having that many parameters is a sign of a possible design issue. – Tenfour04 May 10 '21 at 13:24