๐Ÿ› ๋ฆฌํŒฉํ† ๋ง: ์กฐ๊ฑด๋ถ€๋ฅผ ๋‹คํ˜•์„ฑ์œผ๋กœ ๋ฐ”๊พธ๊ธฐ

Switch ๋ฌธ์€ ์ข…์ข… ์ฝ”๋“œ ๋ƒ„์ƒˆ๋กœ ๊ฐ„์ฃผ๋˜๋ฏ€๋กœ ํ”ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.




๋ฌธ์ œ



Bird์™€ ๊ฐ™์€ ์†์„ฑ์œผ๋กœ ์ •์˜๋œ ๋‹ค์–‘ํ•œ ํ•˜์œ„ ์œ ํ˜•์ด ์žˆ๋Š” ํด๋ž˜์Šค๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

public class Bird
{
    // whatever properties do birds have
    public BirdType Type { get; set; }
}

public enum BirdType
{
    African,
    American,
    European
}


๊ทธ๋Ÿฐ ๋‹ค์Œ ์ฃผ์–ด์ง„ ์ƒˆ์˜ ์†๋„๋ฅผ ๊ฒ€์ƒ‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” ์ƒˆ์˜ ์†๋„๊ฐ€ ์œ ํ˜•์— ๋”ฐ๋ผ ๋‹ค๋ฅด๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•ฝ๊ฐ„์˜ ๋…ผ๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜์ง€๋งŒ ์ถฉ๋ถ„ํžˆ ์‰ฝ๊ฒŒ ๋“ค๋ฆฝ๋‹ˆ๊นŒ? ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

public class Bird
{
    // whatever properties do birds have
    public BirdType Type { get; set; }

    public double GetSpeed()
    {
        switch(Type)
        {
            case African:
                // logic for African birds
            case American:
                // logic for American birds
            case European:
                // logic for European birds
            default:
                // default logic
        }
    }
}


์กฐ๊ธˆ ๋ชป์ƒ๊ฒผ์ง€๋งŒ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ? ๊ทธ๋Ÿฌ๋‚˜ ์—ฌ๊ธฐ์— ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒ์‚ฐ์— ์ผ์ • ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด ์ƒˆ๋กœ์šด ์œ ํ˜•์˜ ์ƒˆ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

public enum BirdType
{
    African,
    American,
    European,
    Asian // new type
}


์ด์ œ ์†๋„๋„ ๊ณ„์‚ฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. "switch ๋ฌธ์— ๋‹ค๋ฅธ ์‚ฌ๋ก€๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”"๋ผ๊ณ  ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ, ๊ทธ๋ ‡๊ฒŒ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๊ฒƒ์€ SOLID์˜ ๊ฐœ๋ฐฉํ˜• ํ์‡„ ์›์น™์„ ์œ„๋ฐ˜ํ•œ๋‹ค๋Š” ์ ์„ ๋ช…์‹ฌํ•˜์‹ญ์‹œ์˜ค! ๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์„ ์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค, ๊ทธ๋ ‡์ฃ ?


ํ•ด๊ฒฐ์ฑ…: ๋‹คํ˜•์„ฑ



๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ†ตํ•ด ์šฐ๋ฆฌ๋Š” ์ƒ์†์ด๋ผ๋Š” ๊ฐœ๋…์„ ๊ฐ–๊ฒŒ ๋˜์—ˆ๊ณ  ์ด๋ฅผ ํ†ตํ•ด ๋‹คํ˜•์„ฑ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ต์ˆ™ํ•˜์ง€ ์•Š์€ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ๋‹คํ˜•์„ฑ์ด๋ž€ ํด๋ž˜์Šค์— ๋”ฐ๋ผ ๊ฐœ์ฒด๋ฅผ ๋‹ค๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์ต์ˆ™ํ•œ ๊ฒƒ ๊ฐ™๋‚˜์š”?

๋‹คํ˜•์„ฑ์„ ์—ผ๋‘์— ๋‘๊ณ  ์œ„์˜ ๋ฌธ์ œ์— ์–ด๋–ป๊ฒŒ ์ ‘๊ทผํ•ด์•ผ ํ• ๊นŒ์š”? Bird ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฑฐ์˜ ๋™์ผํ•˜๊ฒŒ ์‹œ์ž‘ํ•˜์ง€๋งŒ ํ•œ ๊ฐ€์ง€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

public abstract class Bird
{
    public abstract double GetSpeed();
}


์ด์ œ abstract ํ•œ์ •์ž๋ฅผ GetSpeed ๋ฉ”์„œ๋“œ์™€ Bird ํด๋ž˜์Šค ์ž์ฒด์— ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์˜๋ฏธํ•˜๋Š” ๋ฐ”๋Š” Bird ํด๋ž˜์Šค ์ž์ฒด์— ํ•ด๋‹น ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•œ ๊ตฌํ˜„์ด ์—†๊ณ  ์ง์ ‘ ์ธ์Šคํ„ด์Šคํ™”ํ•  ์ˆ˜ ์—†์œผ๋ฉฐ ๋ชจ๋“  ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ์ž์ฒด์ ์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด์ œ ์šฐ๋ฆฌ๊ฐ€ ํ•ด์•ผ ํ•  ์ผ์€ ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค!

public class AfricanBird : Bird
{
    public override double GetSpeed()
    {
        // logic for African birds
    }
}

public class AmericanBird : Bird
{
    public override double GetSpeed()
    {
        // logic for American birds
    }
}

public class EuropeanBird : Bird
{
    public override double GetSpeed()
    {
        // logic for European birds
    }
}


์‹คํ–‰ ์ค‘์ธ ์ฝ”๋“œ์—์„œ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

// Ran on C# Interactive via VisualStudio
> public abstract class Bird
. {
.     public abstract double GetSpeed();
. }
> public class AfricanBird : Bird
. {
.     public override double GetSpeed()
.     {
.         return 1;
.     }
. }
> public class AmericanBird : Bird
. {
.     public override double GetSpeed()
.     {
.         return 0.7;
.     }
. }
> Bird africanBird = new AfricanBird();
> Bird americanBird = new AmericanBird();
> africanBird.GetSpeed()
1
> americanBird.GetSpeed()
0.7


์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•œ ๋ฉ”์„œ๋“œ๋Š” Bird์— ์˜ํ•ด ์„ ์–ธ๋˜์—ˆ์œผ๋ฏ€๋กœ ๋ณ€์ˆ˜๋ฅผ ๊ธฐ๋ณธ ํด๋ž˜์Šค๋กœ ์ •์˜ํ•˜๊ณ  ๊ณ„์† ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์›ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค ๐Ÿ˜‰

์ƒˆ๋กœ์šด ์œ ํ˜•์˜ ์ƒˆ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? ์ƒˆ ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค! ๊ธฐ์กด ํด๋ž˜์Šค๋ฅผ ์ˆ˜์ •ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค! ์šฐ๋ฆฌ๋Š” ๊ฐœ๋ฐฉ ํ์‡„ ์›์น™์„ ์กด์ค‘ํ–ˆ์Šต๋‹ˆ๋‹ค!

  • ์ฐธ๊ณ : ์ˆ˜ํ–‰๋œ ์ด ๋ฆฌํŒฉํ„ฐ๋Š” ๋‹คํ˜•์„ฑ์œผ๋กœ ์กฐ๊ฑด๋ถ€ ๋ฐ”๊พธ๊ธฐ(Replace conditional with Polymorphism)(์ด๋ฆ„์„ ๊ธฐ์–ตํ•˜๊ธฐ๊ฐ€ ์‰ฝ์ฃ ?)
  • ์ž…๋‹ˆ๋‹ค.



    ์ด์ต


  • ์•ž์„œ ์–ธ๊ธ‰ํ•œ ๊ฐœ๋ฐฉํ˜• ํ์‡„ ์›์น™ ์ค€์ˆ˜
  • ๋งŽ์€ ์กฐ๊ฑด๋ฌธ ๋ฐ/๋˜๋Š” switch ๋ฌธ์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ค‘๋ณต ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค
  • .
  • Tell, Don't Ask ์›์น™์„ ์ค€์ˆ˜ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์ฒด ์ž์ฒด๊ฐ€ ์‚ฌ์šฉ์ž๊ฐ€ ์ •๋ณด๋ฅผ "์š”์ฒญ"(์กฐ๊ฑด๋ฌธ์„ ํ†ตํ•ด)ํ•˜๋Š” ๋Œ€์‹  ์‚ฌ์šฉ์ž๊ฐ€ ์•Œ๊ณ  ์‹ถ์€ ๊ฒƒ์„ ์•Œ๋ ค์ค๋‹ˆ๋‹ค
  • .



    ์ฐธ์กฐ


  • Martin Fowler's "Refactoring" book
  • Refactoring.guru: Replace conditional with Polymorphism
  • Switch Statements are like Ants
  • Polymorphism definition
  • ์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ