λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
πŸ–₯ Computer Science/Programming

[πŸ’» Programming] Clean Code - κΉ¨λ—ν•œ ν•¨μˆ˜λŠ” μ–΄λ–»κ²Œ μž‘μ„±ν• κΉŒ?

by Fomagran πŸ’» 2021. 8. 4.
728x90
λ°˜μ‘ν˜•

μ•ˆλ…•ν•˜μ„Έμš” Foma πŸ‘Ÿ μž…λ‹ˆλ‹€!

 

항상 ν•¨μˆ˜λ₯Ό μž‘μ„±ν•˜λ©΄μ„œ "νŒŒλΌλ―Έν„°λŠ” λͺ‡ κ°œκ°€ μ λ‹Ήν• κΉŒ?", "μ–΄λŠμ •λ„ λ‹¨μœ„λ‘œ μ¨μ•Όν• κΉŒ?" λ“±

 

ν•¨μˆ˜λ₯Ό μ μ ˆν•˜κΈ° μ“°κΈ° μœ„ν•΄μ„œ κ³ λ―Όν–ˆμ—ˆλŠ”λ°μš”.

 

"클린 μ½”λ“œ" 책을 ν†΅ν•΄μ„œ κΉ”λ”ν•œ ν•¨μˆ˜λ₯Ό μž‘μ„±ν•˜λŠ” 법에 λŒ€ν•΄ μ•Œκ²Œ λ˜μ–΄ 정리해보렀고 ν•©λ‹ˆλ‹€.


1. 더 μž‘κ²Œ

 

κΉ”λ”ν•œ ν•¨μˆ˜λ₯Ό μž‘μ„±ν•˜κΈ° μœ„ν•΄μ„  이 μ±…μ˜ μ €μžμΈ λ§ˆν‹΄μ€ μ΅œλŒ€ν•œ μž‘κ²Œ 더 μž‘κ²Œ 쓰라고 κ°•μ‘°ν•©λ‹ˆλ‹€.

 

(μ‹€μ œλ‘œ 읡슀트림 ν”„λ‘œκ·Έλž˜λ° 개발자인 "μΌ„νŠΈ λ°±"이 μž‘μ„±ν•œ ν•¨μˆ˜λŠ” 2μ€„μ—μ„œ 4μ€„λ‘œλ°–μ— 이루어져 μžˆμ§€ μ•Šλ‹€κ³  ν•˜λ„€μš”)

 

"κ·Έλ ‡λ‹€λ©΄ μž‘κ²Œ μ“°λŠ” κ²ƒμ˜ 기쀀은 μ–΄λŠ μ •λ„μΌκΉŒμš”?"

 

ν•¨μˆ˜ μ•ˆμ—μ„œ if/else/while문에 μ“°μ΄λŠ” 블둝은 ν•œ 쀄이 μ λ‹Ήν•˜κ³  λ“€μ—¬μ“°κΈ°λŠ” 1λ‹¨μ—μ„œ 2단을 λ„˜μ–΄μ„œλ©΄ μ•ˆλœλ‹€κ³  ν•©λ‹ˆλ‹€.

 

μ΄λ ‡κ²Œ μž‘κ²Œ ν•¨μˆ˜λ₯Ό μž‘μ„±ν•΄μ•Ό 더 μ΄ν•΄ν•˜κΈ° 쉽고 읽기 μ‰¬μš΄ μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€.


2. ν•œκ°€μ§€λ§Œ 해라

 

ν•¨μˆ˜λ₯Ό μž‘κ²Œ μ“°κΈ° μœ„ν•΄μ„  μ–΄λ–»κ²Œ ν•΄μ•Ό ν• κΉŒμš”?

 

적은 일을 ν•΄μ•Ό ν•  κ²ƒμž…λ‹ˆλ‹€.

 

즉, ν•¨μˆ˜ 내에선 μ—¬λŸ¬κ°€μ§€ 일을 μ²˜λ¦¬ν•˜λŠ” 것이 μ•„λ‹Œ ν•œ 개의 ν•¨μˆ˜μ—μ„œ ν•œ 가지 일만 ν•˜λ„λ‘ ν•˜λŠ” 것 μž…λ‹ˆλ‹€.

 

예λ₯Ό λ“€λ©΄ μ•„λž˜μ™€ 같이 계산을 ν•΄μ£ΌλŠ” μ—°μ‚°μžμ— λ”°λΌμ„œ ν•¨μˆ˜κ°€ μžˆλ‹€κ³  κ°€μ •ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

λ‚˜μœ 예 ❌

 

func calculate(n1:Int,n2:Int,op:String) -> Int {
    if op == "*" {
        return n1*n2
    }else if op == "+" {
        return n1+n2
    }else if op == "-" {
        return n1-n2
    }else {
        return n1/n2
    }
}

 

ν•œ 가지 일만 ν•˜λ„λ‘ ν•¨μˆ˜λ₯Ό 짜게 ν•˜λ©΄ μ–΄λ–»κ²Œ λ κΉŒμš”?

 

쒋은 예 πŸ‘πŸ»

 

func add(n1:Int,n2:Int) -> Int {
    n1+n2
}

func minus(n1:Int,n2:Int) -> Int {
    n1-n2
}

func multiply(n1:Int,n2:Int) -> Int {
    return n1*n2
}

func divide(n1:Int,n2:Int) -> Int {
   return n1/n2
}

3. μ„œμˆ μ μΈ 이름을 μ‚¬μš©ν•΄λΌ

 

μ§€λ‚œ "κΉ¨λ—ν•œ μ½”λ“œλž€?" κΈ€μ—μ„œ μœ„ν‚€ μ°½μ‹œμžμΈ μ›Œλ“œλŠ” "μ§μž‘ν–ˆλ˜ κΈ°λŠ₯이 κ·ΈλŒ€λ‘œ μˆ˜ν–‰ν•œλ‹€λ©΄ 쒋은 μ½”λ“œλ‹€." 라고 ν–ˆμŠ΅λ‹ˆλ‹€.

 

즉, ν•¨μˆ˜μ˜ 이름을 μžμ„Έν•˜κ²Œ μ§€μ„μˆ˜λ‘ ν•¨μˆ˜κ°€ μˆ˜ν–‰ν•˜λŠ” κΈ°λŠ₯을 μ§μž‘ν•˜κΈ° μ‰¬μšΈ 것 μž…λ‹ˆλ‹€.

 

아무리 길더라도 μΆ©λΆ„ν•œ μ„€λͺ…이 λ˜λŠ” 이름이 짧고 μ–΄λ €μš΄ 이름보닀 λ‚«λ‹€κ³  λ§ν•©λ‹ˆλ‹€.

 

λ‚˜μœ 예 ❌

 

func isValid(email:String) -> Bool {
    return email.contains("@")
}

 

쒋은 예 πŸ‘πŸ»

 

func isEmailContainsAtsign(email:String) -> Bool {
    return email.contains("@")
}

4. 이상적인 인수

 

ν•¨μˆ˜μ—μ„œ 이상적인 인수의 κ°œμˆ˜λŠ” ν•˜λ‚˜λ„ μ—†λŠ” 것이 κ°€μž₯ μ’‹κ³  λΆˆκ°€ν”Ό ν•œ 경우 μ΄ν•­μ—μ„œ μ‚Όν•­κΉŒμ§€ μ‚¬μš©ν•˜μ§€λ§Œ

 

κ·Έ 이상 즉, 4κ°œλŠ” νŠΉλ³„ν•œ μ΄μœ κ°€ μžˆλ”λΌλ„ μ‚¬μš©ν•˜λ©΄ μ•ˆλœλ‹€κ³  λ§ν•©λ‹ˆλ‹€.

 

κ·Έλ ‡λ‹€λ©΄ μ–΄λ–»κ²Œ 인수λ₯Ό 쀄일 수 μžˆμ„κΉŒμš”?

 

λ°”λ‘œ 객체λ₯Ό μ‚¬μš©ν•˜λŠ” 것과 ν•œ 가지 일만 ν•˜λ„λ‘ ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

 

μ•„λž˜μ™€ 같이 ν’€λ„€μž„μ„ λ§Œλ“€μ–΄ μ£ΌλŠ” ν•¨μˆ˜κ°€ μžˆμŠ΅λ‹ˆλ‹€.

 

ν•˜μ§€λ§Œ μ˜μ–΄λ‘œ 된 이름은 성이 λ’€λ‘œ κ°€κ²Œ ν•΄μ•Όν•˜κ³  ν•œκΈ€λ‘œ 된 이름은 성이 μ•žμœΌλ‘œ κ°€κ²Œ ν•΄μ•Όν•©λ‹ˆλ‹€.

 

λ‚˜μœ 예 ❌

 

func makeFullName(firstName:String,lastName:String,isEnglish:Bool) -> String{
    if isEnglish {
        return lastName + firstName
    }else {
        return firstName + lastName
    }
}

 

쒋은 예 πŸ‘πŸ»

 

μ•„λž˜μ™€ 같이 Nameμ΄λž€ 객체λ₯Ό λ§Œλ“€κ³  μ˜μ–΄λ‘œ 된 이름과 ν•œκΈ€λ‘œ 된 이름 ν’€λ„€μž„μ„ λ§Œλ“œλŠ” ν•¨μˆ˜λ₯Ό λΆ„λ¦¬ν•˜λ©΄

 

3ν•­μ—μ„œ 단항 ν•¨μˆ˜λ‘œ 인수λ₯Ό 쀄일 수 μžˆμŠ΅λ‹ˆλ‹€.

 

struct Name {
    let first:String
    let last:String
}

func makeKoreanFullName(name:Name) -> String{
    return name.first +  name.last
}

func makeEnglishFullName(name:Name) -> String{
    return name.last +  name.first
}

5. 였λ₯˜ 처리

 

보톡 였λ₯˜λ₯Ό μ²˜λ¦¬ν•  λ•Œ ν•¨μˆ˜ λ‚΄μ—μ„œ μΌμ–΄λ‚˜λŠ” 였λ₯˜λΌλ©΄ λ°”λ‘œ μ²˜λ¦¬ν•˜λŠ” κ²½μš°κ°€ λ§Žμ•˜μŠ΅λ‹ˆλ‹€.

 

κ·ΈλŸ¬λ‹€λ³΄λ©΄ 였λ₯˜λ₯Ό μ²˜λ¦¬ν•˜λŠ” μ½”λ“œ try catch ꡬ문 λ“±μœΌλ‘œ ν•¨μˆ˜κ°€ κΈΈμ–΄μ§€κ²Œ λ©λ‹ˆλ‹€.

 

λ˜ν•œ 였λ₯˜λ„ ν•œκ°€μ§€ μž‘μ—… 쀑에 ν•˜λ‚˜μ΄κΈ° λ•Œλ¬Έμ— λ”°λ‘œ λΆ„λ¦¬ν•˜λŠ” 것이 μ’‹λ‹€κ³  λ§ν•©λ‹ˆλ‹€.

 

 

λ‚˜μœ 예 ❌

 

enum UserError:Error{
    case emptyString
    case containSpecialSymbol
    case containNumber
    case negativeNumber
}

struct User {
    let name:String
    let age:Int
}

func signUp(user:User) throws -> User{
    let user = User(name: "Fomagran", age: 26)
    
    if user.name.isEmpty {
        throw UserError.emptyString
    }
    
    if user.name.contains("@") {
        throw UserError.containSpecialSymbol
    }
    
    if user.name.filter({$0.isNumber}).count > 0 {
        throw UserError.containNumber
    }
    
    if user.age < 0 {
        throw UserError.negativeNumber
    }
    
    return user
}

 

쒋은 예 πŸ‘πŸ»

 

였λ₯˜λ₯Ό κ²€μ‚¬ν•˜λŠ” ν•¨μˆ˜μ™€ 였λ₯˜λ₯Ό μ²΄ν¬ν•˜λŠ” ν•¨μˆ˜λ₯Ό λ”°λ‘œ λ§Œλ“€μ–΄μ„œ signUp ν•¨μˆ˜λŠ” κ°„κ²°ν•˜κ²Œ μž‘μ„±ν•˜λ„λ‘ ν•©λ‹ˆλ‹€.

 

func isValidUserInfo(user:User) throws -> User {
    if user.name.isEmpty {
        throw UserError.emptyString
    }
    
    if user.name.contains("@") {
        throw UserError.containSpecialSymbol
    }
    
    if user.name.filter({$0.isNumber}).count > 0 {
        throw UserError.containNumber
    }
    
    if user.age < 0 {
        throw UserError.negativeNumber
    }
    return user
}

func checkUserError(user:User) -> User?{
    do {
        return try isValidUserInfo(user: user)
    }
    catch {
        print(error)
        return nil
    }
}

func signUp(user:User) -> User? {
    let validUser = checkUserError(user: user)
    return validUser
}

 

728x90
λ°˜μ‘ν˜•

λŒ“κΈ€