👨‍🎓
Today I Learned
  • Today-I-Learend
  • 🍎WWDC
    • Developer Tools
      • Testing in Xcode
    • UIKit
      • UIDiffableDataSource
        • [WWDC 19] Advances in UI Data Sources
      • [WWDC2019] Advances in CollectionView Layout
  • 자료구조
    • Heap 자료구조
  • Clean code
    • 네이밍
    • 주석과 포맷팅
    • 함수
    • 클래스
    • 에러 핸들링
    • 가독성 높이기
    • 객체지향
  • Network
    • RestAPI
  • Swift
    • DateType
    • ARC
    • Availablity
    • KeyPath
    • Network
    • Never타입
    • Result
    • Selector
    • 검증함수
    • 메타타입
    • 동시성 프로그래밍
    • 메모리 안전
    • 에러처리
    • 접근제어 (Access Control)
    • 제네릭
    • 주요 프로토콜
  • 알고리즘
    • 그래프
    • 기초 알고리즘
    • 누적합(Prefix)
    • 복잡도
    • 비트마스킹
  • 운영체제
    • 운영체제의 개요
    • 프로세스와 스레드
    • CPU 스케줄링
    • 프로세스 동기화
    • 교착상태
    • 07. 메모리
    • 08.가상 메모리
    • 입출력 장치
    • 파일 시스템
  • UIKit
    • UITableView xib으로 만들어보기
  • 🖊️정보 기록
    • 코코아팟 배포하는 방법
  • iOS Project
    • 채팅 앱 만들기
      • Trouble shooting
      • 1. 디자인
      • 2. AutoLayout
    • 날씨 조회 어플리케이션
      • Figma를 이용한 UI 설계
      • TableView 연결하기
      • Networking
    • MVC -> MVVM으로 구조 변경해보기
      • MVC
      • MVVM
    • OAuth Project
      • 로컬 호스트를 이용한 로그인 페이지 제작
      • Github의 OAuth App 설정
    • Rest API 프로젝트
      • UI설계 (with Figma)
      • Network Model
      • MVVM 구조 전환
  • 🕶️UIKit
    • Compositional Layout
Powered by GitBook
On this page
  • SPR : 함수의 역할은 하나만 할당한다.
  • DRY (Don’t repeat yourself) : 반복하지 말자
  • 파라미터 수는 적게 유지하자
  • 사이드 이펙트를 잘 핸들링하자
  1. Clean code

함수

SPR : 함수의 역할은 하나만 할당한다.

  • 하나의 함수에 역할이 많아지면 오류 발생 가능성이 커지고, 가독성이 떨어지며 테스트를 진행하기 어렵다.

  • 따라서 하나의 함수에 많은 로직을 넣지 말자.

// as-is
func createUser(email, password) -> Bool {
    if email.contains("@") || password.contains("@") {
        //error
        return false
    }

    var user = User()
    user.email = email
    user.password = password

    database.add(user)

    emailClient = EmailClient()
    emailClient.setConfig()
    emailClient.send(email, "회원가입이 완료되었습니다")
    
    return true
}
    
// to-be
func createUser(email: String, password: String) -> Bool { // 주요 로직 실행 함수
    validateCreateUser(email, password)

    user = BuildUser(email, password)

    saveUser(user)
    sendEmail(email)
    return true
}

// 역할 별로 함수를 작성한다.
func validateCreateUser(_ email: String, _ password: String) { }

func Builduser() { }

func saveUser(_ user: User) { }

DRY (Don’t repeat yourself) : 반복하지 말자

  • 반복되는 코드가 많아지면, 전체 코드가 많아진다.

  • 특정 부분에 변경사항이 생기면, 공통적인 모든 부분을 변경해줘야한다.

  • 이에 관심사를 잘 분리하고 의존성을 줄이기 위해 반복되는 코드를 하나의 함수로 만들어서 사용하자.

// as-is

func createUser(email: String, password: String) {
    if email.contains("@") || password.contains("@") {
        //error
        return false
    }

    // code...
}

func updateUser(email: String, password: String) {
        if email.contains("@") || password.contains("@") {
        //error
        return false
    }

    // code...
}
// to-be
func validateCreateUser(_ email: String, _ password: String) -> Bool {
    if email.contains("@") || password.contains("@") {
        //error
        return false
    }
}

func createUser(email, password) {
    guard validateCreateUser(email, password) else { ... }
    // code..
}

func updateUser(email, password) {
    guard validateCreateUser(email, password) else { ... }
    // code..
}

파라미터 수는 적게 유지하자

// as-is
func saveUser(userName: String, email: String, password: String, createAt: Int) {
    ...
}

// to-be
func saveUser(user: User) {
    ...
}

사이드 이펙트를 잘 핸들링하자

  • 사이드 이펙트란? (Side Effect)

    • 함수가 실행되었을 때, 함수 이외의 어떤 것들에 변화를 주는 것을 의미한다.

    • 이를 잘 다루지 못하면 예측하지 못하는 문제가 발생할 수 있다.

    • A, B, C, D라는 함수가 있을 때, A 실행시 B또는 C함수에도 영향을 주는 경우가 Side Effect라고 한다.

    // 사이드 이펙트가 없는 경우
    func getUser(email, password) -> User {
        let user = User(email, password)
        return user
    }
    
    // 사이드 이펙트가 있는 경우
    func updateUser(user) {
        var user = getUser(user.email, user.password)
        user.eail = "newEmail" // 인자로 받은 user 객체를 업데이트한다
        return user
    }
    
    // 사이드 이펙트가 있는 경우
    func createUser(email, password) {
        let user = User(email, password)
        dbSession() // 외부 DB 세션에 변화를 준다.
    }
  • 사이드 이펙트 핸들링하는 방법

    • 코드를 통해 사이드이펙트를 예측할 수 있도록 네이밍을 잘 해야한다.

      • update, set 등 직관적인 prefix를 붙여 암시한다.

    • 함수의 사이드 이펙트가 있는 부분과 없는 부분으로 나누어 관리한다.

      • 명령과 조회를 분리하는 CQRS 방식이 존재한다.

        • 명령(Command) : 사이드이펙트가 존재

        • 조회(Read) : 사이드 이펙트가 없다

      • 하나의 함수에 명령과 조회 모두가 실행된다면, 사이드이펙트 덩어리가 된다. 이를 함수나 클래스로 영역을 나누어 분리시킨다.

    • 순수함수 형태로 사용하여 직관적으로 표현하고, 에러를 방지한다.

      • update 함수를 남발하지 않는다.

      // as-is
      var carts = [Cart]()
      
      // 사이드이펙트 발생
      func addCart(product: Cart) {
          casts.append(product)        // 외부에 있는 carts의 변경
      }
      
      product = Product()
      addCart(product: product)
      // to-be
      var carts = [Cart]()
      
      // 사이드이펙트가 없는 순수함수
      func getAddCart(product: Cart) -> [Cart] {
          return carts + product
      }
      
      carts = getAddCart(product)                // carts를 재선언한다.
Previous주석과 포맷팅Next클래스

Last updated 2 years ago