소프트웨어 디자인: 모델 분리하기🗂️
API 명세에 맞는 객체 모델링을 할 때 할 수 있는 고민을 문답 형식으로 나눠보려 합니다☺️ 1️⃣ Toy , ToyCategory , Person 세 가지 모듈이 있습니다. ‘단일 책임 원칙’, ‘테스트 용이성’ 관점에서 모델링에 대한 질문을 할 수 있습니다. 📝 Toy Feature ``` struct Toy { var id: UUID = UUID() var category: ToyCategory var rating: Double var contact: Person var name: String let brand: String } struct ToyCategory: Identifiable { var id: UUID var name: String } struct Person { var phoneNumber: String var email: String var fullName: String } ``` 🤔 “모듈이 서로 결합했습니다. 각 모듈을 분리해야 할까요?” 💡 우선 세 가지 객체를 하나의 모듈로 봐야 할지 독립된 세 가지 모듈로 봐야 할지를 결정해야 합니다. 엔지니어와 팀의 선택에 따라 결정되지만 이 글에서는 ‘하나의 모듈’로 봅니다. 연관된 모델 객체는 결합하더라도 유지보수 비용이 비교적 적기 때문에 모델 객체의 결합을 분리할 필요 없이 의사결정에 따라 필요한 경우에만 분리하면 됩니다. 코드를 세 개의 독립 모듈로 분리하려면 모듈이 인터페이스를 통해 협력하도록 수정해야 합니다. 모듈을 어떻게 구성할 것인지와 팀이 달성하려는 목표에 따라 다르니 참고해주세요🙂 2️⃣ Feed Feature, Feed API 두 가지 모듈이 있고, 모듈 간 협력하고 있습니다. ‘최소 지식 원칙’, ‘결합도’ 관점에서 모델링에 대한 질문을 할 수 있습니다. 📝 Feed Feature ``` public struct FeedItem: Equatable { public let id: UUID public let description: String? public let location: String? public let imageURL: URL } } extension FeedItem: Decodable { private enum CodingKeys: String, CodingKey { case id case description case location case imageURL = "image" } } ``` 📝 Feed API ``` private struct Root: Decodable { let items: [FeedItem] // ⚠️강결합 발생!!! } ``` 🤔 “Decodable 프로토콜을 채택 중인 Feed Feature의 FeedItem 모델 객체는 디코딩을 위한 CodingKey를 채택하고 있습니다. FeedItem 객체와 Feed API 객체가 협력해야 한다면 두 객체 간 느슨한 결합을 지향해야 할까요?” 💡이 문제 역시 Feed Featrue와 Feed API를 하나의 모듈로 봐야 할지 독립된 모듈로 봐야 할지를 결정해야 합니다. 엔지니어와 팀의 선택에 따라 결정되지만 이 글에서는 ‘독립된 모듈’로 봅니다. ‘최소 지식 원칙’ 관점에서 볼 때 원칙을 위반하는 부분은 FeedItem 디코딩을 도와주는 ‘CodingKey’는 Feed API의 Root가 관심을 가질 지식이 아닙니다. 따라서 원칙을 지키도록 리팩터링하면 좋습니다. 📝 수정된 Feed API ``` private struct Root: Decodable { let items: [FeedItem] let items: [Item] } private struct Item: Decodable { let id: UUID let description: String? let location: String? let image: URL var item: FeedItem { return FeedItem(id: id, description: description, location: location, imageURL: image) } } ``` Feed API는 Feed Feature 모듈 FeedItem 모델 객체의 알아야 할 최소한의 지식만 알도록 수정하는 것이 좋습니다. 사실 이 리팩터링이 유별나 보이기도 하고 신선하기도 하지만 원칙을 지키려는 연습에는 큰 도움이 됩니다👍👍👍