초안은 2018년도에 내 마음대로 작성한 글인데 그때보다 지금의 지식으로 정제하기 위해 고쳐쓰기로 마음먹었다
이 글 본문을 읽기 전에 먼저 VO vs DTO vs DAO vs Domain Model 을 구분할 수 있는지 가슴에 손을 얻고 생각해 봐야할 것 같다
이 글을 적으면서 Fix 하려고 하는 개념이지만 이게 진짜 맞을까? 라는 의심 한구석이 생겨나고 있는데 일단 너무 개념과 용어에 매몰되어 바보가 되진 말자
먼저 객체에 대해 개념 그룹핑을 한다
-
Data Object
- VO
- DTO
-
Entity Object
- Domain
- Database Table
-
Imutable Object
- VO
-
Data Access Object
- DAO
크게 4가지로 구분해보았다 그리고 중요한 점은 위의 4가지 모델을 동일선상에 두고 비교하지 않는다.
동등비교할 대상이라기 보다는 구분해야하는 대상으로 보이기 때문에 개념적인 분기로서 모델을 구분한다. 즉 귀에 걸면 귀걸이 코에 걸면 코걸이 같은 녀석들의 개념 의존성을 구분하고자 한다
서론이기 때문에 가볍게 용어정리를 하면
- VO(Value Object): 값을 생성하면 그 값이 변하지 않을 객체(Read Only)
- DTO(Data Transfer Object): 계층과 계층간의 데이터 전송을 목적으로 생성하는 객체
- 서버 Side : Database data -> Business Layer -> DTO -> Presentation Layer -> API response data(JSON/XML) -> Clinet
- 클라이언트 side : API request data(JSON/XML) -> Presentain Layer -> Business Layer -> DTO -> Data Access Layer -> Database System
- DAO(Data Access Object): 실제로 DA에 접근하는 Layer 에 있는 객체로 data를 가공하는 업무 비즈니스 로직과 구분된다. 즉 database의 data를 조회하거나 조작하는 기능만을 전담하도록 만든 객체
- Domain: 시스템에서 다루려는 대상 그 자체로서 가볍게 설명하자면 database의 Entity와 비교된다 하지만 Table 적으로 보는 DB 관점이 아닌 Object-Class 관점에서 바라보는 객체지향적 객체라고 정의한다
위 내용은 DDD 챕터를 만든다면 추가 적으로 얘기하겠다
본론으로 돌아와서 제목에 관련된 토론을 시작하게 된 글과 함께 시작해보자
- (https://www.slipp.net/questions/19 - 인터페이스 사용에 대한 토론)
흥미로운 부분은 비즈니스 레이어에 외부와 협업이 있으면 Interface가 필요하다는 내용이 있다
아무것도 모르고 기존 MVC 패턴의 코드만 보고 흉내내면 비즈니스의 구현체 마다 Interface를 매번 만드는 노가다성 작업을 맞닥들일 때가 있다
실제 구현 클래스와 1:1 관계로만 사용되는데 이렇게만 사용하면 의미가 있냐는 것이다
의미있게 사용하는 방법에 대해서 필자는 기능적 역할에 대해 어느 정도 세밀한 분리(일단 추측)를 가진 Interface로 나누어서 기능별로 관리하고 필요한 인터페이스를 상속받아 구현하는 것에 대해서 의미 있다고 생각하고 있다
Layer 별로 개발자가 다른 경우(시스템이 달라질 정도여야 가능한 시나리오??)도 멀티로(병렬로) 다양한 구현 클래스들을 생성해야 하는 경우도 필요하다고 생각하고 있다
복잡도에 대한 내용이 있는데 비즈니스적 업무가 복잡하다면 추상화를 통해 Interface를 분리하는 것에 대해도 긍정적으로 생각하고 있다
이런 상황에서 Interface는 공통된 관심사의 분리의 구현체로 생각된다
설계 또는 기획과 같은 부분에서 분리된 내용을 바탕으로 Interface 에서 쪼개진다는 것이다
그렇기 때문에 추상화 라는 개념 속에서 공통된 관심사를 Interface로 분리한 것이다 라는 생각이 드는 글이었고 우리는 개념적으로 공통점과 차이점을 추출 할 수 있어야 이와 같은 기반의 설계를 한다는 생각도 들었다
추상화 -> Interface -> 구현 클래스
이런 식의 규칙도 관심사를 분리하고 로직을 분리하고 필요 의존성에 따라 응집도를 높이고 결합도를 낮추는 행위로서 Interface 생성과 분리를 이해해야 한다고 얘기하고 싶다
위 글의 토론 중에 반복적으로 Interface –> 구현 class의 방법을 지양해야 한다는 말이 나오는데 실제 내가 했던 Ludy라는 플랫폼 개발 업무에서 GameContents 쪽은 추상화의 대상이 되는 Model이 간단하고 그것에 CRUD에 대한 로직이 간단하기 때문에 습관적 사용으로도 구현을 하는데 문제가 없었다
다만 이런 부분에 대해 고민해 보지 못한다면 원래 그렇게 Interface를 항상 만드는 것인 줄 알았을 것도 같다 (멍청이가 되지 말아야 하는 부분)
IoC Container에서 Interface를 사용해서 객체를 생성하는 부분이 있기 때문에 개발실 위키에 있는 계약기반 이런 내용과 관련해서 만드는 것도 객체 생성의 응집력을 높이려면 제대로 만들어진 Interface를 주입해야 한다는 생각도 하게 되었다
즉 Interface를 만드는 것은 이유가 있어서 만드는 것이지 폼으로 만드는 것이 아니라는 것이다
그리고 유연함과 확장성 이라고 썼는데 공통된 것을 모으고 그것들을 차이점들을 분리해서 처리할 수 있는 부분이라고 생각하면 말로는 쉬운 것 같다
인터페이스를 우선 적으로 고민하는 부분도 나중에 유지보수 할 때 확장성에 대한 보험이 될 수 있다는 부분도 공감이 된다
다만 너무 디자인 패턴적으로 매몰되었는지 이 당시 파트장이 내가 Interface를 처음 사용하면서 나도 모르게 불필요한 미래의 확장을 생각해서 뭐든지 Interface로 객체들을 생성하면 단순히 Class로 바꿔주었던 부분도 있었다(오버 엔지니어링은 역효과가 날 수 있다는 생각도 든다)
1:1로 될 것 같으면 지양하지만 뼈와 살의 예를 들어서 뼈의 역할을 인터페이스로 표현하고 살을 붙인다는 표현도 재미있는 표현이었고 Interface로 계약서를 작성하고 계약서대로 개발한다 이런 내용도 쉽게 이해하려는 노력인 것 같다
토론에서 게임 분야 개발자의 1:1 매칭에 대한 반성과 우연히 2개의 구현체에 대한 수정을 하게 되면서 class 상속이 아닌 Interface 상속으로 변하는 것과 공통되는 것을 구분하게 된 것에 대한 장점을 겪어본 것은 개발자가 성장하면서 부딪칠 문제와 해결법들이 공감이 되는 부분도 있다
이 토론의 결론은 Interface 우선 설계가 중요하다로 끝난다 그리고 막판쯤에
개발 방식은 Controller 개발 => Business Layer Interface 도출 => Business Layer Class 구현 => Persistence Layer Interface 도출
이런 형태로 진행되어야 하는데 이 같은 접근 방식이 괜찮다고 생각하냐? 그렇다면 도메인 설계는 어느 시점에 하는 것이 좋을까?
애플리케이션을 개발할 때의 개발 순서에 대해 고민해 봐야겠다 라는 말을 하게 된다 (2탄에서 다룰 내용!)
위 질문에 대해 다시 한번 질문을 하는데 컨트롤러 드리븐 개발은 도메인 설계에서 객체를 조합하거나 컨트롤 할 수 있는 레이어부터 해결해 나가는 방식이 아닐까?
Ludy(플랫폼)에서 Service 층을 나누게 되는데 인게임 상점으로서 처리가 필요한지 웹 상점으로서 처리가 필요한지 생각해야 하는 부분에서 공감이 되었다
즉 분기의 시작이 Controller라면 다른 각각의 Service를 호출할지 혹은 Controller 까지 InGameShopController of WebShopController 분리할지 비즈니스 적으로 확장과 생성을 구분해야 하는 부분으로 이해되었다
그리고 제일 중요한 개념 같은데 인터페이스 설계는 행위의 설계이고 도메인 설계는 실제 업무의 설계/라는 말이 나온다
나는 이게 명사와 동사 같다
도메인 설계(DB Table이라면 Entity라는 것으로)는 명사적인 것으로 상품, 포인트, 구매 환전 같은 명사적인 설계이고
행위의 설계는 상품을 조회하다 / 포인트를 수정하다 / 웹상점으로 구매하다 / 인게임상점으로 구매하다 / 포인트를 게임머니로 환전하다 / 실제 돈을 게임머니로 환전하다 등등 명사를 활용하는 부분을 만드는 것으로 생각이 된다
이런 생각으로 인터페이스 우선 설계를 하게 된다면
ERD 같은 것을 그리기 전에 마인드맵을 먼저 그려서 도메인을 중심으로 가지 치기 하면서 뻗어나간 행위들을 이어 나가면
필요한 컬럼이 무엇인지 그리고 필요한 if나 switch case가 어떤 상황이 있는지 또는 다른 도메인과 결합 될 것이 무엇인지 그림으로 그리고 나서
테이블의 컬럼이나 Interface에 사용될 Method들을 수집하는 것이 비즈니스의 복잡도를 낮춰가면서 개발하는 방법으로 생각된다
말로 설명한다는 것이 무척이나 어려운데 구현과 일상 세계간 차이야 당연히 있을 것이다
핵심은 구현에만 치중하지말고 확장에 유연하고 변경에 엄격한 시스템 구조가 되어야 품질관리와 품질보증이 되는 시스템의 시작이라는 생각으로 1탄을 마무리 한다
'Computer Science > 소프트웨어 공학' 카테고리의 다른 글
Interface와 Application 제작 2 (0) | 2021.02.22 |
---|---|
Domain Model vs DTO (0) | 2019.02.28 |