1부 강의:
앱 아키텍쳐 구축 강의1
문제: 중복되는 네트워킹, 빌드시간
앱의 확장성. 커질 수 있다. → 아키텍쳐 고려의 필요성
확장 가능한 앱 아키텍처의 특징 → 교재 참고
변화에 유용하도록 decoupling 필요
자동화테스트 필요성: 코드의 일관성 유지
2부 강의:
Composition → dry원칙, 단일책임원칙 지킬 수 있다. 앱이 처음에는 작아도 점점 커지고 뷰가 많이질 경우 작은 모듈일 경우 이해가 쉽다.
- MVC → MVVM 에서 ViewController의 코드를 ViewModel로 옮기면서, Massive ViewModel의 가능성 존재.
- Ribs의 경우에도 Interupt가 커질 수 있다. Massive ribs.
- → 즉 아키텍쳐만의 문제는 아닐 수 있음. Composition의 필요성.
상속시 원치않는 메소드 사용하지 않기위해, 빈메소드 만들거나 바꿔서 사용 → 부모의 상속에 거부 → 리스코프원칙에 위배, 코드를 쓰는 사람이 예상치 못한 버그 발생 가능성. 예를들어 UIView는 Frame으로 위치, 사이즈 변경가능하나 UISwitch의 경우 크기 바꾸어지지 않음.
상속없이 기능확장의 예: SwiftUI의 ViewModifier.
A라는 화면위에 B라는 화면이 올라가 있는 예 → A 뷰컨트롤러 클래스를 상속받고 setUpViews 메소드를 상속받고 B View를 add하는 클래스를 만든다? → 유지보수가 어려울 수 있다.
대신 A,B ViewController 각각 만들고 C ViewController에 property에 두 개를 부른다.(사진참조)
→ Composition을 활용하여 상속없이 복잡해보이는 기능을 단순한 API로 만들 수 있다. NavigationController, TabBarController도 내부 property에 배치만 하면 동작하는 것 처럼.
모듈화 하여 복잡한 참조관계 해소, 또한 Public 하지 않으면 다른 모듈에서 접근조차 안되므로 side effect가 적다.
택시 모듈 Composition 사진 참조(p11)
모듈 Composition 해서 트리구조 형태가 됨 → 이해가 쉬움 → 유지보수가 쉽다.
Ribs, VIPER 찾아보기
기타
4종류의 map: array, optional, publisher, result → 모두 generic type임, transform 함수를 인자로 받음. 이 특징.
Array 도 generic이었다.
let ageString: String? = "10"
let result5 = ageString.map{ Int($0) }
// optional 2번 -> flatMap의 필요성. (optional 자체를 없애는 compactMap과 차이 주의)
다음과 같은 표현방식으로 depth유지할 수 있다. map, flatMap을 활용한 함수 composition
let a = UserDefaults.standard.data(forKey: "key")
let s = a
.flatMap { try? JSONDecoder().decode(MyModel.self, from: $0)}
.map(.name)
.map{"Hello ($0)"}