관리 메뉴

김종권의 iOS 앱 개발 알아가기

[Refactoring] 6-1. 캡슐화 (레코드 캡슐화하기) 본문

Refactoring (리펙토링)

[Refactoring] 6-1. 캡슐화 (레코드 캡슐화하기)

jake-kim 2023. 3. 21. 01:27

레코드란?

  • 데이터를 저장하는것을 의미
  • 대표적인 레코드 표현 구조는 list, dictionary, hash 3가지

캡슐화란?

  • 클라이언트 코드에서(=사용하는쪽) 사용하는 것만 관심있고 내부에서는 어떻게 처리하고 있는지 모르게하는 방법
  • 구현 내용 일부를 "은닉화"한다고도 불림

캡슐화하는 이유?

  • 구현을 숨긴다는것은 클라이언트 코드에서 접근하지 못한다는 의미로, 구현부가 유연하게 변경되어도 클라이언트쪽 코드를 신경쓰지 않아도 되어 곧 개발자는 사용하는쪽을 신경쓰지 않고 구현부 하나만 신경쓸수 있는 장점이 존재

레코드 캡슐화

  • 데이터를 저장하는 부분을 클라이언트 코드쪽에서 모르게끔 하는것
    • 기대효과: 캡슐화되어 있으면 데이터가 변경되어도 클라이언트 코드는 영향이 가지 않기 때문에 더욱 유연한 코딩이 가능
    • 레코드 캡슐화의 가장 대표적인 방법: 클래스나 Struct로 만들어서 사용하는쪽에서 method로 접근하는것

레코드 캡슐화

ex) data가 name, job이 주어질 때 캡슐화하지 않은 코드

// data
var data = [AnyHashable: Any]()
data["name"] = "jake"
data["job"] = "developer"

// client code
let name = data["name"]
let job = data["job"]
  • struct를 만들어서 레코드를 캡슐화 진행
    • 일반적으로 swift에서는 codable을 사용하면 편하지만 예시를 위해 codable 없이 작성
    • 객체의 상태를 나타내는 stored proprety는 모두 private으로하여 상태에관한 정보를 은닉화 시키고 메소드를 통해 정보를 가져올수 있도록 구현
struct Account {
    private let name: String
    private let job: String
    
    init(data: [AnyHashable: Any]) {
        name = data["name"] as? String ?? ""
        job = data["job"] as? String ?? ""
    }
    
    func getName() -> String {
        name
    }
    func getJob() -> String {
        job
    }
}

// data
var data = [AnyHashable: Any]()
data["name"] = "jake"
data["job"] = "developer"

// client code
let account = Account(data: data)
let name = account.getName()
let job = account.getJob()
  • swift에서는 computed property가 존재하므로 method가 아닌 computed property를 통해 getter, setter 제공할것
    • stored property는 웬만하면 private으로 은닉화할것
  • 위처럼 캡슐화하는 이유를 이해하는게 가장 중요
    • 캡슐화하는 이유 - 사용하는쪽에서는 객체의 상태에는 관심이 없고 그저 필요한 정보인 name, job만 신경쓰면 되므로 프로그래밍할때 여러가지를 생각하지 않고 하나만 생각하며 프로그래밍이 가능
    • 만약 Account 구조를 수정할때도 getName, getJob 부분만 클라이언트 코드에서 의존하고 있으니, 그 부분을 제외하고는 나머지 부분들은 클라이언트 코드를 신경쓰면서 코딩하지 않아도 되는 간편함이 존재

* 참고

- Refactoring (Marting Flowler)

Comments