๊ธ€ ์ž‘์„ฑ์ž: ๊ฐœ๋ฐœํ•˜๋Š” ํ›ˆ์ด

ํ…œํ”Œ๋ฆฟ ๋ฉ”์„œ๋“œ ํŒจํ„ด

ํ…œํ”Œ๋ฆฟ ๋ฉ”์†Œ๋“œ ํŒจํ„ด์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ณจ๊ฒฉ์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ํ…œํ”Œ๋ฆฟ ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์ผ๋ถ€ ๋‹จ๊ณ„๋ฅผ ์„œ๋ธŒํด๋ž˜์Šค์—์„œ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ตฌ์กฐ๋Š” ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•˜๋ฉด์„œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ํŠน์ • ๋‹จ๊ณ„๋ฅผ ์„œ๋ธŒํด๋ž˜์Šค์—์„œ ์žฌ์ •์˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

- ํ—ค๋“œํผ์ŠคํŠธ ๋””์ž์ธ ํŒจํ„ด

 

ํ…œํ”Œ๋ฆฟ ๋ฉ”์„œ๋“œ ํŒจํ„ด์€ ๋‹จ๊ณ„์ ์ธ ๊ณผ์ •์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ถ”์ƒ์ ์œผ๋กœ ์ •์˜ํ•˜๊ณ , ๊ทธ ์ค‘ ์ผ๋ถ€๋ฅผ ์„œ๋ธŒ ํด๋ž˜์Šค์—์„œ ํ•„์š”์— ๋”ฐ๋ผ ์ง์ ‘ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์šฐ๋ฆฌ๊ฐ€ ํšŒ์›๊ฐ€์ž…์„ ๊ตฌํ˜„ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค๋ฉด, ์•„๋ž˜์ฒ˜๋Ÿผ ๋‹จ๊ณ„๋ฅผ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๊ฒ ์ฃ .

  1. ์•„์ด๋””๋ฅผ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค.
  2. ์ค‘๋ณต๊ฒ€์‚ฌ๋ฅผ ํ•œ๋‹ค.
  3. ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค.
  4. ๋น„๋ฐ€๋ฒˆํ˜ธ ๊ทœ์น™์„ ํ™•์ธํ•œ๋‹ค.
  5. ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋‹ค์‹œ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค.
  6. ๋‘ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
  7. ๊ฐ€์ž… ์™„๋ฃŒ๋ฅผ ํ‘œ์‹œํ•œ๋‹ค.

์ด ๋•Œ, ๋งŒ์•ฝ ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋น„๋ฐ€๋ฒˆํ˜ธ ๊ทœ์น™๋งŒ ๋‹ฌ๋ผ์ ธ์•ผ ํ•œ๋‹ค๋ฉด ์–ด๋–จ๊นŒ์š”? ๋˜‘๊ฐ™์€ ๊ณผ์ •์˜ ์ฝ”๋“œ๋ฅผ ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค๋Š” ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๊ฒ ๊ณ , ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ข‹๊ฒ ์ฃ . ํ…œํ”Œ๋ฆฟ ๋ฉ”์„œ๋“œ ํŒจํ„ด์„ ์ด์šฉํ•ด์„œ ํ•œ๋ฒˆ ๋ฌธ์ œ๋ฅผ ํ’€์–ด๋ด…์‹œ๋‹ค.

 

ํ…œํ”Œ๋ฆฟ ๋ฉ”์„œ๋“œ ํŒจํ„ด ์ดํ•ดํ•˜๊ธฐ

UML์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ทธ๋ ค๋ดค๋Š”๋ฐ์š”, ์Šค์œ„ํ”„ํŠธ์— ๋งž์ถฐ์„œ ํ•˜๋ ค๋‹ˆ ์‰ฝ์ง€ ์•Š์€ ๋ถ€๋ถ„์ด ์žˆ๋„ค์š”.. AbstractClass ํ”„๋กœํ† ์ฝœ์€ ํ”„๋กœํ† ์ฝœ์ด์ง€๋งŒ ๋‹ค๋ฅธ ๊ฐ์ฒด์ง€ํ–ฅ ์–ธ์–ด์—์„œ ์ œ๊ณตํ•˜๋Š” ์ถ”์ƒ ํด๋ž˜์Šค์˜ ์—ญํ• ์„ ํ•˜๊ฒŒ๋ฉ๋‹ˆ๋‹ค. templateMethod๋ผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ณ , ๊ฐ ๋‹จ๊ณ„๋ณ„๋กœ ์ง„ํ–‰๋˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ๋Œ€ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ฃ . 

์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์•„๋‹Œ ์ถ”์ƒ ํด๋ž˜์Šค๋กœ ์ •์˜๊ฐ€ ๋˜์–ด ์žˆ๋Š” ์ด์œ ๋Š” ์ •์˜์—์„œ ์„ค๋ช…ํ–ˆ๋˜ "์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์ผ๋ถ€ ๋‹จ๊ณ„" ๋•Œ๋ฌธ์ธ๋ฐ์š”, ๋ชจ๋“  ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋‹จ๊ณ„๋ฅผ ์žฌ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ผ๋ถ€๋งŒ ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ณตํ†ต๋˜๋Š” ๋‹จ๊ฒŒ์— ๋Œ€ํ•œ ๊ตฌํ˜„์€ ์ถ”์ƒ ํด๋ž˜์Šค์—์„œ ์ œ๊ณต์„ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์Šค์œ„ํ”„ํŠธ๋Š” ์ถ”์ƒ ํด๋ž˜์Šค๊ฐ€ ์—†์œผ๋‹ˆ protocol๋กœ ์„ ์–ธํ•˜๊ณ  extension์— ๊ธฐ๋ณธ ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒ ๋„ค์š”. 

 

ํšŒ์›๊ฐ€์ž… ํ”„๋กœ๊ทธ๋žจ ๋งŒ๋“ค๊ธฐ

๊ทธ๋Ÿผ ์šฐ๋ฆฌ๊ฐ€ ์ดํ•ดํ•œ๋Œ€๋กœ ํšŒ์›๊ฐ€์ž… ํ”„๋กœ๊ทธ๋žจ์„ ํ•œ๋ฒˆ ๊ตฌํ˜„ํ•ด๋ณผ๊ฒŒ์š”.

protocol RegistrationSupportable {
    // template method
    func register()

    // steps
    func inputId()
    func validateId()
    func inputPassword()
    func validatePassword()
    func reinputPassword()
    func validateReInputPassword()
    func presentSuccess()
}

extension RegistrationSupportable {
    func register() {
        inputId()
        validateId()
        inputPassword()
        validatePassword()
        reinputPassword()
        validateReInputPassword()
        presentSuccess()
    }
}

๋จผ์ € ์ถ”์ƒํด๋ž˜์Šค์˜ ์—ญํ• ์„ ํ•  ํ”„๋กœํ† ์ฝœ์ธ RegistrationSupportable ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์—ˆ์–ด์š”. ๊ทธ๋ฆฌ๊ณ  ํ…œํ”Œ๋ฆฟ ๋ฉ”์„œ๋“œ๊ฐ€ ๋  register ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•œ ์ •์˜๋ฅผ extension์— ์ถ”๊ฐ€ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ๋‹จ๊ณ„๋ณ„ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์•„์ง ๊ตฌํ˜„์ด ๋˜์–ด์žˆ์ง€ ์•Š์ง€๋งŒ, ํ…œํ”Œ๋ฆฟ ๋ฉ”์„œ๋“œ๋ฅผ ํ™•์ธํ•˜๋ฉด ํšŒ์›๊ฐ€์ž…์ด ์–ด๋–ค ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์ณ์„œ ์ง„ํ–‰๋ ์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์ฃ .

๊ทธ๋Ÿผ ์ด์ œ ๊ณตํ†ต๋˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ธฐ๋ณธ๋ฉ”์„œ๋“œ๋กœ ์ •์˜ํ•ด๋ณผํ…๋ฐ์š”, ์•„์ด๋””์™€ ํŒจ์Šค์›Œ๋“œ์˜ ๊ทœ์น™์„ ํ™•์ธํ•˜๋Š” ๋ถ€๋ถ„ ๋ง๊ณ ๋Š” ๋ชจ๋‘ ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒ ์ฃ ? ๊ตฌํ˜„ํ•ด์ค์‹œ๋‹ค. ํŽธ์˜๋ฅผ ์œ„ํ•ด์„œ ์‹ค์ œ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ตฌํ˜„ํ•˜์ง€๋Š” ์•Š๊ณ  ์ถœ๋ ฅ๋ฌธ์œผ๋กœ ๋Œ€์ฒดํ• ๊ฒŒ์š”. 

extension RegistrationSupportable {
    func register() {
        inputId()
        validateId()
        inputPassword()
        validatePassword()
        reinputPassword()
        validateReInputPassword()
        presentSuccess()
    }

    func inputId() {
        print("input id")
    }

    func inputPassword() {
        print("input password")
    }

    func reinputPassword() {
        print("reinput password")
    }

    func validateReInputPassword(){
        print("password and repassword should be identical")
    }

    func presentSuccess() {
        print("Success!")
    }
}

 

์ด์ œ ๋‘ ๊ฐ€์ง€ ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋น„๋ฐ€๋ฒˆํ˜ธ์™€ ์•„์ด๋””๋ฅผ ๊ฒ€์‚ฌํ•˜๋Š” ๋ถ€๋ถ„๋งŒ ์žฌ์ •์˜๋  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋ ค๊ณ  ํ•˜๋Š”๋ฐ์š”, ์•„์ด๋””์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์—„๊ฒฉํ•˜๊ฒŒ ๊ฒ€์‚ฌํ•˜๋Š” ์‹œ๋‚˜๋ฆฌ์˜ค์ธ StrongRegistration๊ณผ ์—„๊ฒฉํ•˜์ง€ ์•Š๊ฒŒ ๊ฒ€์‚ฌํ•˜๋Š” LooseRegisration์„ ๋งŒ๋“ค์–ด์ฃผ๊ฒ ์Šต๋‹ˆ๋‹ค.

final class LooseRuleRegistration: RegistrationSupportable {
    func validatePassword() {
        print("password should be more than 1 letter")
    }

    func validateId() {
        print("id should be more than 1 letter and alphanumeric letters are allowed")
    }
}

final class StrongRuleRegistration: RegistrationSupportable {
    func validatePassword() {
        print("password should be more than 8 letters. At leat 2 speical characters should be included")
    }

    func validateId() {
        print("id should be more than 5 letter and only alphabet is allowed")
    }
}

๋‘ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ  validatePassword์™€ validateId ๋ฉ”์„œ๋“œ๋งŒ ๊ฐ๊ฐ ์žฌ์ •์˜๋ฅผ ํ•ด์ฃผ์—ˆ์–ด์š”.

์‚ฌ์šฉํ•ด๋ณผ๊นŒ์š”?

let weakReg = LooseRuleRegistration()
weakReg.register()

// input id
// id should be more than 1 letter and alphanumeric letters are allowed
// input password
// password should be more than 1 letter
// reinput password
// password and repassword should be identical
// Success!

let strongReg = StrongRuleRegistration()
strongReg.register()

// input id
// id should be more than 5 letter and only alphabet is allowed
// input password
// password should be more than 8 letters. At leat 2 speical characters should be included
// reinput password
// password and repassword should be identical
// Success!

์ด๋ ‡๊ฒŒ ๋‹ค๋ฅธ ๋ชจ๋“  ๋‹จ๊ณ„๋Š” ๋™์ผํ•˜์ง€๋งŒ ์ผ๋ถ€๋งŒ ์žฌ์ •์˜๋˜์–ด์„œ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๋Š” ๊ตฌ์กฐ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋งˆ๋ฌด๋ฆฌ

ํ…œํ”Œ๋ฆฟ ๋ฉ”์„œ๋“œ ํŒจํ„ด์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๋‹จ๊ณ„๋ฅผ ํ•œ๋ˆˆ์— ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๊ณ  ๊ทธ ์ค‘ ์ผ๋ถ€๋งŒ์„ ์žฌ์ •์˜ํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ์œ ์šฉํ•œ ํŒจํ„ด์ด์—ˆ๋Š”๋ฐ์š”, ์‚ฌ์‹ค ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•ด์•ผํ• ์ง€๋Š” ๊ฐ์ด ์ž˜ ์•ˆ์˜ค๋„ค์š”. ์ง€๊ธˆ ๋“œ๋Š” ์ƒ๊ฐ์€ ์–ด๋–ค ๋‹จ๊ณ„๊ฐ€ ์ •ํ•ด์ ธ์žˆ๊ณ , ๋‘ ๊ฐœ ์ด์ƒ์˜ ์ƒํ™ฉ์—์„œ ์ผ๋ถ€ ๋‹จ๊ณ„๋งŒ ๋‹ค๋ฅธ ๋™์ž‘์œผ๋กœ ์ง„ํ–‰๋˜์–ด์•ผํ•  ๋•Œ, ํ…œํ”Œ๋ฆฟ ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค๊ณ  ์™ธ๋ถ€์—์„œ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์žฌ์ •์˜๊ฐ€ ๋˜์—ˆ๋Š”์ง€ ์•„๋‹Œ์ง€ ์•Œ์ง€ ๋ชปํ•œ ์ƒํƒœ๋กœ ์›ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋Š” ๊ฒƒ ๊ฐ™์•„์š”. ์œ„ ์˜ˆ์ œ์—์„œ ํด๋ผ์ด์–ธํŠธ๋Š” register๋งŒ ํ˜ธ์ถœํ•˜๋ฉด ๋˜๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ์š”. 

๊ทธ๋Ÿผ ์ด๋งŒ ์ค„์ด๊ฒ ์Šต๋‹ˆ๋‹ค. ์˜ค๋Š˜๋„ ์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!