vendredi 27 novembre 2015

should refactor this if else

someone gave me example about how to refactor if-else code.

function doSomething(a) {
    if (a === 'x') {
        doX();
    } else if (x === 'y') {
        doY();
    } else {
        doZ();
    }
}

it should refactored to:

function doSomething(a) {
    var lookup = {x: doX, y: doY}, def = doZ;
    lookup[a] ? lookup[a]() : def();
}

but I said it is a bad example. the first piece of code is sample enough. I think it is ok to have those if-else. The second piece of code is not as clear as the first one.

then he gave me another example:

function rank(score) {
    var star
    if (score < 89) {
        star = 9
    } else if (score > 74 && score < 90) {
        star = 8
    } else if (score > 59 && score < 75) {
        star = 7
    } else if (score > 44 && score < 60) {
        star = 6
    } else if (score > 29 && score < 45) {
        star = 5
    } else if (score >10 && score < 30) {
        star = 4
    } else if (score > 8 && score < 11) {
        star = 3
    } else if (score > 6 && score < 9) {
        star = 2
    } else if (score < 7) {
        star = 1
    }
    return star
}  

I still though it is accepted. it is not big or complicated. easy to know what is doing. I will code like this just remove the condition after &&. I don't like to write so much if-else like this, but I cannot find a better way.

I asked he how to refacot it, he gave me the code he refactored.

function rank(score) {
    var ranges = {
        9: [90: Infinity],
        8: [75, 90],
        7: [60, 75],
        6: [45, 60],
        5: [30, 45],
        4: [11, 30],
        3: [9, 11],
        2: [7, 9],
        1: [-Infinity, 7]
    }
    var count = _.findKey(ranges, function(range) {
        return range[0] <= score && score < range[1]
    })
    return count >>> 0
}

I think the code refactored is more complicated then the origin code, easy to make mistake. and I don't like to use a hash map to refactor the if-else.

he said I should read some article about functional programming. they don't have if-else. they use pattern-matching and guard. I know litte about Scala and Haskell. I think pattern-matching just like switch statment. just more powerful.

I coped a piece of Haskell code from wiki:

describeLetter :: Char -> String
describeLetter c
   | c >= 'a' && c <= 'z' = "Lower case"
   | c >= 'A' && c <= 'Z' = "Upper case"
   | otherwise            = "Not an ASCII letter"

If I use Haskell to write this logic, I will write it like this, and I think it is similar to the origin code, not the code refactored by him.

My question is which code is better, the origin one or refactored one? why? or there is any other way to refactor this code?

Is it a good practice to use hash map to refactor if-else?

Thanks for your ansower!

Aucun commentaire:

Enregistrer un commentaire