소프트웨어 아키텍처 수업을 통해 도메인 설계의 중요성을 깊이 있게 배웠다. 1학기 동안 기능을 중점으로 생각하여 객체지향 설계를 학습하면서 유스케이스와 클래스 다이어그램을 통해 순수한 비즈니스 로직을 설계하는 방법을 익혔는데, 이 과정에서 도메인 모델은 현실 세계를 그대로 반영하며 기술적인 제약 없이 순수하게 유지될 수 있었다.
하지만 2학기에는 기능의 품질을 높이기 위해 실제 프레임워크를 도입하면서 이론과 실제 구현 사이의 간극을 경험하게 됐다.
실제 프로젝트에서 클래스 다이어그램과 DB 테이블 설계를 비교하면서 도메인 모델 순수성의 중요성을 깊이 이해하게 됐다. 예를 들어, Insurance와 Guarantee는 분명히 다른 비즈니스 개념임에도 불구하고, DB 설계 과정에서 성능 최적화를 위해 이 두 개념을 하나의 테이블로 합치면서 도메인 모델의 순수성이 훼손되는 경험을 했다. 이는 기술적 편의성이 비즈니스 로직을 지배하게 된 전형적인 사례였다.
Spring 프레임워크와 JPA를 도입하면서 이러한 도전은 더욱 커졌다. JPA 엔티티 매핑을 위해 테이블 구조를 단순화하고 싶은 유혹이 있었고, 실제로 Guarantee의 적은 속성 수를 이유로 Insurance 테이블에 통합하기도 했다. 하지만 이런 결정이 당장의 성능 향상을 가져올 수 있더라도, 도메인 모델의 본질을 해치는 것임을 깨달았다.
이러한 도전을 해결하기 위해 성능 최적화와 도메인 모델의 순수성은 반드시 상충하는 것이 아니라는 점을 배웠다. DTO 패턴을 활용하면 두 가지 목표를 모두 달성할 수 있었다.
// 도메인 모델 - 순수성 유지
public class Insurance {
private Guarantee guarantee;
// 비즈니스 로직
}
// 성능 최적화를 위한 DTO
public class InsuranceDetailDTO {
private String insuranceName;
private String guaranteeName;
// 조회 최적화를 위한 구조
}
또한 처음에는 단순해 보이는 엔티티도 시스템이 발전하면서 복잡해질 수 있다는 점을 고려해야 했다. 예를 들어, 속성이 몇 개 없는 Guarantee를 별도 테이블로 관리하는 것이 과도해 보였지만, 시스템이 발전하면서 새로운 요구사항이 추가될 수 있고, 이때 독립된 엔티티로 존재하는 것이 변경과 확장에 훨씬 유리하다는 것을 깨달았다.
이론으로만 알고 있던 도메인 주도 설계(DDD)의 원칙들을 실제 프로젝트에 적용하면서, 이론과 현실 사이의 간극을 체감했다. DDD는 복잡한 비즈니스 로직을 소프트웨어로 구현할 때, 도메인 전문가와 개발자가 같은 언어로 소통하며 비즈니스의 본질에 충실한 설계를 만들어가는 방법론이다. 핵심은 기술적인 구현보다 비즈니스 도메인 자체에 집중하여, 실제 문제 영역을 정확하게 반영하는 모델을 만드는 것이다.
Spring, JPA와 같은 프레임워크는 개발의 효율성, 품질을 높여주는 도구일 뿐, 이들이 도메인 모델을 지배해서는 안 된다는 점을 깊이 이해하게 됐다. 순수한 도메인 모델을 유지하면서도 실용적인 구현을 하기 위해서는 추가적인 계층이나 패턴의 도입이 필요했고, 이는 단순히 원칙을 고수하는 것이 아니라 원칙을 지키면서도 실용적인 해결책을 찾아가는 과정의 중요성을 보여줬다.
이러한 경험을 통해 단기적인 편의성보다는 장기적인 유지보수성과 확장성이 더 중요하다는 것을 배웠으며, 도메인 모델의 순수성을 지키면서도 실용적인 구현을 할 수 있는 방법을 찾는 것이 진정한 아키텍처의 역할임을 깨달았다.
iOS 개발에서 도메인 모델의 순수성과 비즈니스 로직의 독립성은 매우 중요한 의미를 가진다. UIKit이나 SwiftUI 같은 프레임워크는 단순히 비즈니스 로직을 시각적으로 표현하는 도구일 뿐이며, 핵심 비즈니스 로직은 이러한 프레임워크로부터 독립적으로 설계되어야 한다.
아래는 2학기에 진행하는 프로젝트를 간단하게 SwiftUI 프로젝트로 작성한 Clean Architecture이다. 실제로는 React - Spring 프로젝트이다.
이러한 도메인 모델의 순수성을 지키기 위해 Clean Architecture를 적용할 수 있다. Clean Architecture는 앱을 세 가지 주요 계층으로 나누어 각 계층의 책임을 명확히 분리한다. 가장 안쪽의 Domain Layer는 순수한 비즈니스 로직을 포함하며, 외부 프레임워크나 기술에 대한 의존성이 없다. 예를 들어, 보험 상품의 보장 내용을 계산하는 로직은 이 계층에서 순수하게 구현된다.
중간의 Data Layer는 Domain Layer에서 정의한 인터페이스를 실제로 구현하는 계층이다. SwiftData와 같은 데이터 저장소를 사용할 때도 도메인 모델과 데이터 모델을 분리하고, 데이터 매핑 계층을 통해 이들을 변환하는 방식을 사용한다. 이를 통해 데이터 저장 기술이 변경되더라도 도메인 모델은 영향을 받지 않는다.
가장 바깥쪽의 Presentation Layer는 SwiftUI Views와 ViewModels로 구성되며, ViewModel은 순수한 도메인 로직과 UI 사이의 중재자 역할을 한다. 특히 SwiftUI와 같은 선언적 UI 프레임워크에서는 상태 관리와 UI 업데이트가 긴밀하게 연결되어 있지만, 비즈니스 로직은 여전히 도메인 계층에 순수하게 유지되어야 한다.
이러한 계층 구조에서 가장 중요한 원칙은 의존성의 방향이다. 안쪽 계층은 바깥쪽 계층을 알지 못해야 하며, 이를 통해 도메인 모델의 순수성이 보장된다. 이러한 구조의 실질적인 이점은 테스트 용이성과 유지보수성의 향상이다. 도메인 로직이 UI나 데이터 계층으로부터 분리되어 있어 단위 테스트가 용이하며, 특정 계층의 변경이 다른 계층에 영향을 미치지 않는다.
초기에는 이러한 구조를 위해 더 많은 코드와 설계가 필요할 수 있지만, 장기적으로는 코드의 유지보수성과 확장성이 크게 향상된다. 특히 비즈니스 로직의 변경이 필요할 때 UI 코드를 수정할 필요가 없어져 유지보수가 훨씬 쉬워진다. 이처럼 도메인 모델의 순수성을 지키는 것은 단순히 이론적인 개념이 아니라, 실제 개발에서 큰 가치를 가지는 실용적인 접근 방식이다.
iOS 개발자로서의 성장 방향에 대해 고민하면서 몇 가지 중요한 인사이트를 얻었다.
첫째, 도메인 모델의 순수성을 지키는 것이 매우 중요하다는 것을 이론적으로 배웠다. 지금까지 진행했던 프로젝트를 돌아보았을 때, 성능 최적화나 기술적 제약 때문에 도메인 로직이 UI나 데이터 계층과 혼재되어 있는데, 이는 장기적으로 코드의 유지보수를 어렵게 만들 수 있다는 것을 깨달았다. 앞으로는 성능이나 기술적 문제는 별도의 계층에서 해결하고 비즈니스 로직은 순수하게 유지하는 Clean Architecture를 적용해보고 싶다.
둘째, Swift 생태계에 대한 깊이 있는 이해가 필요하다. 앞으로 Protocol Oriented Programming, SwiftUI, Combine 등 Swift의 현대적인 패러다임과 프레임워크를 학습하고 적용해보고 싶다. 특히 SwiftUI의 선언형 UI와 Combine의 반응형 프로그래밍은 코드의 유지보수성과 가독성을 크게 향상시킬 수 있을 것으로 기대된다.
마지막으로, 이론과 실무 사이의 균형이 중요하다는 것을 깊이 느꼈다. Clean Architecture나 새로운 기술 스택을 도입할 때는 팀의 상황과 프로젝트의 특성을 고려한 현실적인 판단이 필요하다. 개인 프로젝트를 통해 이러한 새로운 아키텍처와 기술들을 먼저 실험해보고, 그 경험을 바탕으로 실무에 점진적으로 도입하는 방식으로 접근하고자 한다.
이런 고민들을 통해, 앞으로는 순수한 도메인 설계의 중요성을 실제 프로젝트에 적용하면서도 실용적인 타협점을 찾을 줄 아는 개발자로 성장하고 싶다. 새로운 기술과 패턴을 적극적으로 학습하고 실험하면서, 동시에 실무에서의 실용성도 놓치지 않는 균형 잡힌 시각을 유지하려 한다.