Replace Conditional With Polymorphism, ์กฐ๊ฑด๋ถ€ ๋กœ์ง์„ ๋‹คํ˜•์„ฑ์œผ๋กœ ๋ฐ”๊พธ๊ธฐ๋ฅผ ์•Œ์•„๋ณด์ž.

์š”์•ฝ

์ฝ”๋“œ

switch (bird.type) {
    case '์œ ๋Ÿฝ ์ œ๋น„':
        return "๋ณดํ†ต์ด๋‹ค";
    case '์•„ํ”„๋ฆฌ์นด ์ œ๋น„':
        return (bird.numberOfCoconuts > 2) ? "์ง€์ณค๋‹ค" : "๋ณดํ†ต์ด๋‹ค";
    case '๋…ธ๋ฅด์›จ์ด ํŒŒ๋ž‘ ์•ต๋ฌด':
        return (bird.voltage > 100) ? "๊ทธ์„๋ ธ๋‹ค" : "์˜ˆ์˜๋‹ค";
    default:
        return "์•Œ ์ˆ˜ ์—†๋‹ค";
}
class EuropeanSwallow {
    get plumage() {
        return "๋ณดํ†ต์ด๋‹ค";
    }
}
 
class AfricanSwallow {
    get plumage() {
        return (this.numberOfCoconuts > 2) ? "์ง€์ณค๋‹ค" : "๋ณดํ†ต์ด๋‹ค";
    }
}
 
class NorwegianBlueSwallow {
    get plumage() {
        return (this.voltage > 100) ? "๊ทธ์„๋ ธ๋‹ค" : "์˜ˆ์˜๋‹ค";
    }
}

๋ฐฐ๊ฒฝ

  • ์กฐ๊ฑด๋ถ€ ๋กœ์ง์€ ํ”„๋กœ๊ทธ๋žจ์„ ์ฝ๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ ๋‹ค.
  • ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ์ง๊ด€์ ์œผ๋กœ ๊ตฌ์กฐํ™”ํ•  ์ˆ˜ ์žˆ์„๊นŒ?
  • ๋” ๋†’์€ ์ˆ˜์ค€์˜ ๊ฐœ๋…์„ ๋„์ž…ํ•˜๋ฉด ์ด๋ฅผ ๋ถ„๋ฆฌ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.
  • ํด๋ž˜์Šค์™€ ๋‹คํ˜•์„ฑ์ด๋‹ค.
  • ๊ฐ ํƒ€์ž…์ด ์ž์‹ ๋งŒ์˜ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜๋ฉด ์ข‹๊ฒ ๋‹ค.

์ ˆ์ฐจ

  1. ๋‹คํ˜•์  ๋™์ž‘์„ ํ‘œํ˜„ํ•˜๋Š” ํด๋ž˜์Šค๋“ค์ด ์—†๋‹ค๋ฉด ํ•˜๋‚˜ ๋งŒ๋“ ๋‹ค. ๊ธฐ์™•์ด๋ฉด ์ธ์Šคํ„ด์Šค๋ฅผ ์•Œ์•„์„œ ๋งŒ๋“ค์–ด ๋ฐ˜ํ™˜ํ•˜๋Š” ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜๋„ ํ•จ๊ป˜ ๋งŒ๋“ ๋‹ค. (์‚ฌ์šฉํ•˜๋Š”์ชฝ์—์„œ ์ด๊ฒŒ ๋” ํŽธํ•˜๋‹ค.)
  2. ํ˜ธ์ถœํ•˜๋Š” ์ชฝ์—์„œ ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์ˆ˜์ •ํ•œ๋‹ค.
  3. ์กฐ๊ฑด๋ถ€ ๋กœ์ง์„ ์ผ๋‹จ ์Šˆํผ ํด๋ž˜์Šค๋กœ ์˜ฎ๊ธด๋‹ค.
  4. ์„œ๋ธŒ ํด๋ž˜์Šค ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•œ๋‹ค. ์กฐ๊ฑด๋ถ€ ๋กœ์ง ๋ฉ”์„œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œ ํ•œ๋‹ค.
  5. ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋‹ค๋ฅธ ์„œ๋ธŒ ํด๋ž˜์Šค์—๋„ ์ ์šฉํ•œ๋‹ค.
  6. ์Šˆํผ ํด๋ž˜์Šค์—๋Š” ๊ธฐ๋ณธ ๋™์ž‘๋งŒ ๋‚จ๊ธด๋‹ค.

์˜ˆ์‹œ

function plumages(birds) {
    return new Map(birds.map(b => [b.name, plumage(b)]));
}
 
function speeds(birds) {
    return new Map(birds.map(b => [b.name, airSpeedVelocity(b)]));
}
 
function plumage(bird) {
    switch (bird.type) {
        case '์œ ๋Ÿฝ ์ œ๋น„':
            return "๋ณดํ†ต์ด๋‹ค";
        case '์•„ํ”„๋ฆฌ์นด ์ œ๋น„':
            return (bird.numberOfCoconuts > 2) ? "์ง€์ณค๋‹ค" : "๋ณดํ†ต์ด๋‹ค";
        case '๋…ธ๋ฅด์›จ์ด ํŒŒ๋ž‘ ์•ต๋ฌด':
            return (bird.voltage > 100) ? "๊ทธ์„๋ ธ๋‹ค" : "์˜ˆ์˜๋‹ค";
        default:
            return "์•Œ ์ˆ˜ ์—†๋‹ค";
    }
}
 
function airSpeedVelocity(bird) {
    switch (bird.type) {
        case '์œ ๋Ÿฝ ์ œ๋น„':
            return 35;
        case '์•„ํ”„๋ฆฌ์นด ์ œ๋น„':
            return 40 - 2 * bird.numberOfCoconuts;
        case '๋…ธ๋ฅด์›จ์ด ํŒŒ๋ž‘ ์•ต๋ฌด':
            return (bird.isNailed) ? 0 : 10 + bird.voltage / 10;
        default:
            return null;
    }
}
  • ์ƒˆ์˜ ์ข…์— ๋”ฐ๋ฅธ ๋น„ํ–‰ ์†๋„์™€ ๊นƒํ„ธ ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.
  • ์ƒˆ ์ข…๋ฅ˜์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ๋ช‡ ๊ฐœ ๋ณด์ธ๋‹ค.
function plumages(birds) {
    return new Map(birds.map(b => [b.name, plumage(b)]));
}
 
function speeds(birds) {
    return new Map(birds.map(b => [b.name, airSpeedVelocity(b)]));
}
 
function plumage(bird) {
    new Bird(bird).plumage;
}
 
function airSpeedVelocity(bird) {
    new Bird(bird).airSpeedVelocity;
}
 
class Bird {
    constructor(birdObject) {
        Object.assign(this, birdObject);
    }
 
    get plumage() {
        switch (this.type) {
            case '์œ ๋Ÿฝ ์ œ๋น„':
                return "๋ณดํ†ต์ด๋‹ค";
            case '์•„ํ”„๋ฆฌ์นด ์ œ๋น„':
                return (this.numberOfCoconuts > 2) ? "์ง€์ณค๋‹ค" : "๋ณดํ†ต์ด๋‹ค";
            case '๋…ธ๋ฅด์›จ์ด ํŒŒ๋ž‘ ์•ต๋ฌด':
                return (this.voltage > 100) ? "๊ทธ์„๋ ธ๋‹ค" : "์˜ˆ์˜๋‹ค";
            default:
                return "์•Œ ์ˆ˜ ์—†๋‹ค";
        }
    }
 
    get airSpeedVelocity() {
        switch (this.type) {
            case '์œ ๋Ÿฝ ์ œ๋น„':
                return 35;
            case '์•„ํ”„๋ฆฌ์นด ์ œ๋น„':
                return 40 - 2 * this.numberOfCoconuts;
            case '๋…ธ๋ฅด์›จ์ด ํŒŒ๋ž‘ ์•ต๋ฌด':
                return (this.isNailed) ? 0 : 10 + this.voltage / 10;
            default:
                return null;
        }
    }
}
  • ์ผ๋‹จ ์Šˆํผ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์—ˆ๊ณ , ๊ทธ ์•ˆ์— ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์ž.
  • ์•„ ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜๋„ ์ถ”๊ฐ€ํ•ด์ฃผ์ž.
function plumages(birds) {
    return new Map(birds.map(b => [b.name, plumage(b)]));
}
 
function speeds(birds) {
    return new Map(birds.map(b => [b.name, airSpeedVelocity(b)]));
}
 
function plumage(bird) {
    createBird(bird).plumage;
}
 
function airSpeedVelocity(bird) {
    createBird(bird).airSpeedVelocity;
}
 
function createBird(bird) {
    switch (bird.type) {
        case '์œ ๋Ÿฝ ์ œ๋น„':
            return new EuropeanSwallow(bird);
        case '์•„ํ”„๋ฆฌ์นด ์ œ๋น„':
            return new AfricanSwallow(bird);
        case '๋…ธ๋ฅด์›จ์ด ํŒŒ๋ž‘ ์•ต๋ฌด':
            return new NorwegianBlueSwallow(bird);
        default:
            return new Bird(bird);
    }
}
 
class Bird {
    constructor(birdObject) {
        Object.assign(this, birdObject);
    }
 
    get plumage() {
        switch (this.type) {
            case '์œ ๋Ÿฝ ์ œ๋น„':
                return "๋ณดํ†ต์ด๋‹ค";
            case '์•„ํ”„๋ฆฌ์นด ์ œ๋น„':
                return (this.numberOfCoconuts > 2) ? "์ง€์ณค๋‹ค" : "๋ณดํ†ต์ด๋‹ค";
            case '๋…ธ๋ฅด์›จ์ด ํŒŒ๋ž‘ ์•ต๋ฌด':
                return (this.voltage > 100) ? "๊ทธ์„๋ ธ๋‹ค" : "์˜ˆ์˜๋‹ค";
            default:
                return "์•Œ ์ˆ˜ ์—†๋‹ค";
        }
    }
 
    get airSpeedVelocity() {
        switch (this.type) {
            case '์œ ๋Ÿฝ ์ œ๋น„':
                return 35;
            case '์•„ํ”„๋ฆฌ์นด ์ œ๋น„':
                return 40 - 2 * this.numberOfCoconuts;
            case '๋…ธ๋ฅด์›จ์ด ํŒŒ๋ž‘ ์•ต๋ฌด':
                return (this.isNailed) ? 0 : 10 + this.voltage / 10;
            default:
                return null;
        }
    }
}
 
class EuropeanSwallow extends Bird {
}
 
class AfricanSwallow extends Bird {
}
 
class NorwegianBlueSwallow extends Bird {
}
  • ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค์—ˆ๊ณ , ์ด๊ฑธ ํ˜ธ์ถœํ•˜๋„๋ก ๋ณ€๊ฒฝํ–ˆ๋‹ค.
  • ๊ทธ๋ฆฌ๊ณ  ์„œ๋ธŒ ํด๋ž˜์Šค๋“ค์„ ์ผ๋‹จ ๋งŒ๋“ค์–ด๋ดค๋‹ค.
  • ๋กœ์ง์ด ๋ถ„๋ฆฌ๋˜์ง€๋Š” ์•Š์•˜์œผ๋‹ˆ ์ด๊ฑธ ์ฒ˜๋ฆฌํ•ด๋ณด์ž.
function plumages(birds) {
    return new Map(birds.map(b => [b.name, plumage(b)]));
}
 
function speeds(birds) {
    return new Map(birds.map(b => [b.name, airSpeedVelocity(b)]));
}
 
function plumage(bird) {
    createBird(bird).plumage;
}
 
function airSpeedVelocity(bird) {
    createBird(bird).airSpeedVelocity;
}
 
function createBird(bird) {
    switch (bird.type) {
        case '์œ ๋Ÿฝ ์ œ๋น„':
            return new EuropeanSwallow(bird);
        case '์•„ํ”„๋ฆฌ์นด ์ œ๋น„':
            return new AfricanSwallow(bird);
        case '๋…ธ๋ฅด์›จ์ด ํŒŒ๋ž‘ ์•ต๋ฌด':
            return new NorwegianBlueSwallow(bird);
        default:
            return new Bird(bird);
    }
}
 
class Bird {
    constructor(birdObject) {
        Object.assign(this, birdObject);
    }
 
    get plumage() {
        return "์•Œ ์ˆ˜ ์—†๋‹ค";
    }
 
    get airSpeedVelocity() {
        return null;
    }
}
 
class EuropeanSwallow extends Bird {
    get plumage() {
        return "๋ณดํ†ต์ด๋‹ค";
    }
}
 
class AfricanSwallow extends Bird {
    get plumage() {
        return (this.numberOfCoconuts > 2) ? "์ง€์ณค๋‹ค" : "๋ณดํ†ต์ด๋‹ค";
    }
}
 
class NorwegianBlueSwallow extends Bird {
    get plumage() {
        return (this.voltage > 100) ? "๊ทธ์„๋ ธ๋‹ค" : "์˜ˆ์˜๋‹ค";
    }
}

Reference