관리 메뉴

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

[iOS - swift] Clean Code(클린 코드) - 7. 소프트웨어의 경계 본문

Clean Code (클린 코드)

[iOS - swift] Clean Code(클린 코드) - 7. 소프트웨어의 경계

jake-kim 2021. 11. 18. 23:06

소프트웨어의 경계

  • 모든 소프트웨어를 직접 개발하는 경우는 드물고, 프레임워크를 이용하여 작성하는데 이때 외부 코드를 작성하려는 코드에 깔끔하게 통합이 필수
  • 소프트웨어의 경계를 깔끔하게 처리하여 깔끔하게 통합

소프트웨어의 경계가 무너지기 쉬운 경우

  • 인터페이스 제공자 vs 인터페이스 사용자
    • 제공자: 적용성을 최대한 높이면 더 많은 고객이 구매하니까, 제네릭하게 작성
    • 사용자: 자신의 요구에 집중하는 인터페이스를 원하는 상황

소프트웨어의 경계 모듈 예시

  • MyArray 모듈 - 제공자
protocol MyArray {
    func get(key: String) -> Any
}

class MyArrayImpl: MyArray {
    
    ...
    
    var datas = [String: Any]()
    
    func get(key: String) -> Any {
        return datas[key]
    }
}
  • 사용자
    • Sensor 타입을 사용하고 싶은 경우, type casting이 일일이 필요한 문제
    • 사용하는 입장에서는 Map 모듈 자체가 Sensor타입에 대해 정의되어 있다면 타입 캐스팅이 불필요하므로 Sensor타입을 원하는 상태 
let sensor = MyArray()
let s = sensor.get(key: sensorId) as? Sensor
  • Generics를 사용한 경우에도 문제점 발생
    • 사용자 입장에서 Generics타입인 것을 알필요 없이 단순히 Sensor 타입임을 원하는 상태
let sensor = MyArray<Sensor>()
let s = sensor.get(key: sensorId)
  • 해결 방법 - Wrapper 클래스를 사용하여 Sensor타입만을 위한 모듈로 사용
    • 경계 인터페이스인 MyArray를 Sensor안으로 숨기는 형태
    • MyArray 인터페이스가 변하더라도 Sensor내부만 변경되고 사용할때는 변경이 없는 형태
    • Sensor 클래스는 프로그램에 필요한 인터페이스만 제공하므로 코드는 이해하기 쉽고, 오용하기는 어려운 형태
class Sensor {
    private sensors = MyArray()
    
    func getById(_ id: String) -> Sensor? {
        return sensors.get(id) as? Sensor
    }
}

경계 살피고 익히기

  • 일반적인 방법
    • 보통 사용법이 익숙하지 않고 막 가져온 프레임워크를 사용하려고 할때 첫번째로 문서를 읽으면서 사용법을 익히고 코드를 작성하여 예상대로 동작하는지 확인하는 방법
  • 더 좋은 방법 - `학습 테스트`
    • 외부 코드는 익히기 어렵고, 외부 코드를 통합하기 어려우므로 우리쪽 코드를 작성하여 외부 코드를 호출하는 대신 먼저 간단한 테스트 케이스를 작성하여 외부 코드를 익히는 방향
    • 학습 테스트는 사용하려는 방식대로 외부 API를 호출하고 통제된 환경에서 API를 제대로 이해하는지를 확인하는 용도
    • 통합했을때도 패키지가 우리의 코드와 호환되리라는 보장이 없으므로 학습 테스트 코드가 있다면 패키지가 변경되었거나, 우리의 코드가 변경되었을때 재검정이 가능

* 참고: Clean Code (로버트 C. 마틴)

Comments