VO
Value Object: 값을 생성 시 설정하면 그 값이 변하지 않는 객체 (Read only)
내부에 Getter Setter 매소드로 이루어진 클래스
DTO
Data Transfer Object: 계층과 계층간의 데이터 전송을 목적으로 합니다. 만 VO와 동일하게 사용 가능
다른 시스템으로 전달하는 작업을 처리하는 객체
Ex) 서버 측 : Database data -> DTO -> Business Layer -> API(JSON/XML) -> Clinet
클라이언트 측 : Server -> API(JSON/XML) -> DTO -> Business Layer -> View or Database System
DAO
Data Access Object: 실질적으로 DB에 접근하는 객체 한마디로 Database의 Entity에 access 하는 트랜잭션 객체이다.
DB에 접근하는 로직과 데이터를 가공하는 업무 비즈니스 로직을 분리하고 Domain Logic으로부터 Persistence Mechanism(Database CRUD)를 숨기기 위해 사용한다 (적절한 설계로 요구사항이 변경되어도 Domain Logic을 변경하는 것이 아니라 DAO만 바꾸면 된다.)
Persistence 계층: Database에 CRUD하는 계층
간단히 더 설명하면 DB와 연결하기 위해서 매번 커넥션을 생성하는데 작업 하나하나마다 커넥션이 생성되면 엄청난 오버헤드가 발생할 수 있음 그래서 커넥션 풀 이런 곳에서 커넥션 객체를 미리 생성해 놓고 그것을 가져다 만 쓰는 방법으로 설계하는 것 그리고 다 쓰고 나면 리소스를 반환하는데 이런 커넥션 개수는 풀에서 관리하고 로직에 의해 DB에 접근하는 객체는 유일한 하나만 사용하는 구조에서 DAO를 사용
DB에서 데이터를 조회하거나 조작하는 기능을 전담하도록 만든 오브젝트
https://www.slipp.net/questions/19
Interface 사용에 대한 토론
흥미로운 부분은 비즈니스 레이어에 외부와 협업이 있으면 Interface가 필요하다는 내용이 있습니다.
아마도 필자는 비즈니스의 구현체 마다 Interface를 만들어야 하는 노가다성 작업에서 의문이 생겼던 것 같습니다.
구현 클래스와 1:1 관계로 사용되는 부분의 얘기가 있는데 이렇게만 사용하면 의미가 있냐는 것이다
의미있게 사용하는 방법에 대해서 필자는 기능적 역할에 대해 어느 정도 세밀한 분리(일단 추측)를 가진 Interface로 나누어서 관리하고 필요한 인터페이스를 상속받아 구현하는 것에 대해서 의미 있다고 생각하고 있습니다.
Layer 별 개발자가 다른 경우도 다양한 구현 클래스들에 대해 멀티로(병렬로) 진행을 위한 경우도 필요하다고 생각하고 있습니다.
혼자서 다 하는 경우는 불필요한 규칙 작업으로도 생각하고 있습니다.
복잡도에 대한 내용이 있는데 데이터를 처리하고 만들어 내는 업무의 복잡도인지 여러 저장소(DB)나 수단(파일) 또는 환경(Web, OS별)과 같은 시스템적 복잡도를 말하는지는 모르겠지만 추상화를 통해 Interface를 분리하는 것에 대해도 긍정적으로 생각하고 있습니다.
일단 이러한 상황에서는 Interface는 공통된 관심사의 분리의 구현체로 생각됩니다. 로직상 분리한 내용을 Interface 에서 쪼개 넣는 것입니다.
추상화 라는 어려운 개념 속에서 공통된 관심사로 분리한 구현체라는 부분 라는 생각이 드는 글이었고
추상화 -> Interface -> 구현 클래스
이런 식의 규칙도 위의 내용과 관계가 있지 않을 까 생각됩니다.
토론 중에 습관적으로 Interface –> 구현 class의 방법을 지양해야 한다는 말이 나오는데
Ludy에서 GameContent 쪽은 추상화의 대상이 되는 Model이 간단하고 그것에 CRUD에 대한 로직이 간단하기 때문에 습관적 사용으로도 충분히 구현을 하는데 문제가 없습니다. 다만 이런 부분에 대해 고민해 보지 못한다면 원래 그렇게 Interface를 항상 만드는 것인 줄 알 것도 같습니다.
IoC Container에서 Interface를 사용해서 객체를 생성하기 부분이 있기 때문에 개발실 위키에 있는 계약기반 이런 내용과 관련해서 만드는 것이지 다른 개발을 하더라도 당연히 Interface가 습관적으로 붙어야 한다는 생각을 하면 안될 것 같았습니다.
또는 유연함과 확장성 이라고 썼는데 내공이 강한 사람이라 어렵게 말 한지는 모르겠지만 그냥 공통된 것을 모으고 그것에 따라 분리해서 처리할 수 있는 부분이라고 생각하면 쉬운 것 같습니다. 그리고 나중에 유지보수 할 때 도 포함 보험이 될 수 있다는 부분은 공감이 됩니다.
생각해보면 Interface를 처음 사용했을 때 나도 모르게 불필요한 미래의 확장을 생각하며 Interface를 만들어 생성하면 파트장님이 Class로 바꿔주었던 부분이 스쳐 지나 갑니다.
1:1로 될 것 같으면 지양하지만 뼈와 살의 예를 들어서 뼈의 역할을 인터페이스로 표현하고 살을 붙인다는 표현도 나름 재미있는 표현 같습니다. 계약서를 작성하고 계약서대로 개발한다 이런 내용도 비슷한 의미인 것 같습니다.
토론에서 게임 쪽 개발자의 1:1 매칭에 대한 반성과 우연히 2개의 구현체에 대한 수정을 하게 되면서 class 상속이 아닌 Interface 상속으로 변하는 것과 공통되는 것을 구분하게 된 것에 대한 이점을 겪어본 것은 개발자로서 겪을 문제들과 해결법들이 공감이 되는 것 같습니다.
결론은 Interface 우선 설계가 중요하다 로 끝납니다.
막판쯤에
이럴 경우 개발 방식은 Controller 개발 => Business Layer Interface 도출 => Business Layer Class 구현 => Persistence Layer Interface 도출과 같은 형태로 진행되어야 하는데 이 같은 접근 방식으로 구현해야 된다. 이 같은 접근 방식이 괜찮다고 생각하냐? 그렇다면 도메인 설계는 어느 시점에 하는 것이 좋을까? 애플리케이션을 개발할 때의 개발 순서에 대해 고민해 봐야겠다 라는 말을 합니다.
컨트롤러 드리븐 개발은 도메인 설계를 실제 조합하거나 컨트롤 할 수 있는 레이어부터 해결해 나가는 방식 아닐까?
이런 말도 있습니다. Ludy에서라면 Service 층을 나누게 되는데 인게임상점으로서 처리가 필요한지 웹상점으로서 처리가 필요한지 생각해야 하는 부분에서는 공감이 되는 것 같습니다.
그리고 제일 중요한 개념 같은데
인터페이스 설계는 행위의 설계이고 도메인 설계는 실제 업무의 설계라는 말이 있습니다.
저는 이게 명사와 동사 같습니다.
도메인 설계(DB Table이라면 Entity라는 것이 될 듯)는 명사적인 것 상품(간단이해) 포인트(??) 구매 환전 같은 명사적인 설계이고
행위의 설계는 상품을 조회하다 / 포인트를 수정하다 / 웹상점으로 구매하다 / 인게임상점으로 구매하다 /
포인트를 게임머니로 환전하다 / 실제 돈을 게임머니로 환전하다 등등 명사를 활용하는 부분을 만드는 것이지 않을까 생각이 됩니다.
그렇다면 저의 생각으로 인터페이스 우선 설계를 하게 된다면 저는 ERD 같은 것을 그리기 전에 마인드맵을 먼저 그려보겠습니다. 도메인을 중심으로 가지 치기 한 듯한 행위들의 조합을 계속 이어 나가면서 필요한 컬럼이 뭔지 필요한 if나 switch case가 뭔지 또는 다른 가지나 다른 도메인과 연결될 것이 무엇인지 계속 가지를 치고 그것을 가지고 테이블 컬럼이나 Interface에 사용될 Method들을 수집할 것 같습니다.
다만 구현에 치중한 생각이 많아서 구현과 일상세계간 차이가 있는데 그 부분이 막 맴돌아서 인지 잘 설명을 못하는 것 같네요 그렇다고 구현이 빠르거나 기술적으로 많이 아는 것도 아닌데 구현을 어떻게 할 지가 먼저이다 보니 아직 있지도 않은 것을 고민 할 때 시행착오는 무조건 있는 것 같습니다. 조금만 더 천천히 생각하는 것이 뭔지 알아야 할 것 같습니다. 그래도 파트회의에서 잘 정리해 주시니 관련된 생각을 정리할 수가 있습니다.
https://www.slipp.net/questions/21
앞 글에서 말한 컨트롤러 드리븐
1. Controller 개발
2. Business Layer Interface 도출 (Operate Contract)
3. Business Layer Class 구현 (Da or Biz)
4. Persistence Layer Interface 도출 (Data Contract)
애플리케이션 개발은 어떤 순서로 하면 좋을까?
위의 내용과 이어지는 내용입니다. 대충 순번을 매겨보면 아래와 같습니다.
1. 대략적인 도메인을 설계한다. (Model Class – Code first or business Model)
즉, 대략적인 클래스 구조를 잡는 것이 먼저이다 (모델 설계).
2. 클래스 구조를 잡은 후 속성들을 하나씩 채워 나간다. (column or property) (모델의 속성 설계)
현재 JPA를 사용하고 있기 때문에 각 속성에 데이터베이스와의 매핑 정보를 추가해야 한다. 하지만 처음 구현할 때는 매핑은 하지 않은 상태로 기본적인 뼈대와 속성 추가에만 집중한다.
3. 만족할만한 수준으로 뼈대가 완성되면 이때부터 데이터베이스에 대한 매핑 정보를 추가하고 Repository를 구현한다. (DAO or DA의 기초 interface))
Repository는 Spring Data JPA를 사용하고 있기 때문에 기본적인 CRUD 기능만 가능한 상태로 유지한다.
여기까지 일단락을 지은 후
4. Controller를 추가하고 JSP를 만들어 기본적인 화면 흐름을 구현하고 확인한다. (Controller 에서 Business를 구분)
5. 이 과정을 마친 후에 Business Layer를 하나씩 추가해 Controller와 Repository를 연결하는 방식을 취한다.
물론 도메인 모델에 대한 속성이나 구조는 기능을 하나씩 구현해 가면서 계속해서 발전해 나간다.
(위 컨트롤러 드리븐의 2,3,4 번의 일을 하는 것)
위 시점에 Business Layer의 Interface를 도출하기 가장 좋은 시점은 Controller를 구현한 후 요구사항을 만족하기 위한 Business Layer를 만들어 가능 과정이지 않을까 생각한다. 라는 생각을 나타냈습니다. 즉 실질적인 로직은 Controller 이후부터 보게 된다는 말인 것 같습니다.
하지만 이 방법이 적절한지는 모르겠다. 지금까지 특별히 정해진 원칙 없이 내가 필요하다고 생각하는 시점에 하나씩 추가하는 방식을 취했기 때문이다. 그렇다보니 Interface에 메소드를 하나 추가하는 것을 너무 쉽게 생각하는 것이 아닐까라는 의구심이 든다. "Business Layer에 Interface를 만들어야 할까?" 글에서도 언급했지만 Interface와 구현 클래스가 1:1 관계라면 Interface를 만들지 않았다. 특별히 필요성을 느끼지 못했기 때문이다. 그런데 Interface를 만들지 않고 바로 구현 클래스로 넘어가다 보니 Interface의 인자와 반환 값에 대해 신경 쓰는 시간보다 바로 구현을 고민하는 상황이 되는 것은 아닌가라는 생각도 해본다.
이런 정도의 내공을 가진 사람도 interface에 대한 Input과 Output 보다 내부 구현을 바로 고민하는 것에 대해 느끼는 부분에서 저도 하는 고민이 시간이 쌓여도 쉽게 풀리지 않는 구나 라는 생각이 들었습니다. 아무래도 정답이 없는 것에 대한 고민은 개발자가 평생 겪는 고민 같은 것이고 만약 답을 내려도 잘못하다간 시니어가 되었을 때 내 답을 고집하게 될 수도 있을 것 같다는 생각이 들었습니다. 기준을 정한다는 게 누구나 겪는 고민이라는 부분이 눈에 띄었습니다.
그리고 아래 토론에서 C기반의 헤더파일을 인터페이스에 비유하는 부분이나 그렇기 때문에 헤더파일에 Function을 추가하는 거랑 Interface나 Class에 Method를 추가하는 것에 대한 차이를 논하는 것은 진짜 참신하게 놀라웠습니다. 결과적으로 문법적인 영역에서 검증이 불가능한부분 이라고 말하고 있네요
Object(Class) != Structure + Function 와 같은 간단히 넘어갈 개념도 잡고 늘어지는게… 좀 피곤한 느낌도 있습니다…
Message passing 입니다. Method Call을 Function Call 관점에서 보는 것이 아니라, 특정 Object에 Message를 보낸다는 형태로 보는 관점이죠. 이 관점에서 Interface를 바라보면, 정의되어 있는 Recive Message 에 대한 규칙
이 말을 보면 Object를 가지고 Request / Response를 하는 느낌입니다. 단순히 Getter와 Setter만 해도 조회와 저장이라는 Message를 보내고 Return을 받는 느낌입니다. Call / Return 은 Method / Function이 같고 Object로의 Message 전달이나 특정 로직에 의한 가공이 Request / Response 처럼 추가된 느낌입니다.
하나의 전제조건이 있었습니다.
Interface 설계를 (좀 더 이상적으로) 하려면, 설계자는 필히 외부 API 설계 경험이 있어야 합니다
최근에 Interface를 사용하거나 Web API나 Ludy를 사용했던 부분이 조금은 더 고민하게 하지 않았나 싶습니다.
"Facebook API 고쳐주세요!"하면 "있는 걸로 하세요. 다음 버전에는 고려해 볼께요."라는 이야기가 나오는게 정상이지
"고객님 죄송합니다. 바로 고쳐 드릴께요."라고 할 리가 없다고 봅니다
이 부분이 너무 찔리고 있습니다…. .. 초기 개발 수준에는 Interface의 역할 조차도 없다고 봐야겠습니다. 그냥 비슷한데 결과만 다른 메소드 하나 추가하면 저런 요구사항은 아무것도 아닌 것 같습니다.
변화가 발생했을 때 어디까지 영향이 가는지 예측이 힘들면 새로 만드는 개발자들의 특성상, 1:1 매칭되는 클래스나 인터페이스나 메소드나 이런류의 결과가 계속 나오는 될 것 같습니다. 나쁜 처리법은 고쳐야 하는 부분인 것 같습니다.
이 부분의 정확한 이유 중에 하나로 생각되는 부분에서 1:1로 개발하는 이유가 전체 구조에 대한 고민은 적게하고 당장 요구한 부분만 고민을 하면서 개발하게 되는 이유인 것 같습니다.
요구사항만 들어주면 되고 내부 구조는 갉아먹고 있었던 것이었죠…… 근데 진짜 고민했는데도 어쩔 수 없이 1번 2번 매소드나 생성자를 만들 때 기존 구조상에서 좌절해서 포기하고 저런 식으로 만든 적도 있었습니다. (전체적으로 바꿔야 하는 10년이상의 시스템에서)
https://www.slipp.net/questions/22
맨 처음에 봤던 글이지만 여기는 내용이 어려웠습니다.
제가 생각할 수 있는 것은 계층과 계층간에 data를 주고 받을 때 DTO를 사용할 것이며 그 DTO안에는 Persistent Object(DB로부터 얻은 결과 or Business Model 들을 가지고 있다) 라는 생각이 한계입니다.
루디 입장에서는 DA나 Biz에서 DB에서 사용하는 Model들의 형태를 하나의 객체에서 주고 받는데 사용해야겠다 라는 생각이 듭니다.
https://www.slipp.net/wiki/pages/viewpage.action?pageId=4489243
마지막으로 어플리케이션은 어떻게 만드는가의 댓글에 있는 내용에서 고민해봐야 하는 부분이 있습니다.
Java를 만든사람들이 보기에, Object-oriented Programming 은 "How" 보다는 "What"에 초점을 맞추고 있다고 합니다. 여기서 대명사처럼 쓰인 Java는 OOP라는 개념으로 생각됩니다.
전체 개발 과정에서 "What"에 관심을 가지면, Interface 설계는 자동으로 따라오는 거라고 봅니다. 이 말이 매우 어렵습니다.
왜 인지는 모르겠지만 일단 저는 항상 How가 생각납니다. How를 생각하면 일정도 산정할 수 있을 것 같고 문제를 푸는 기분으로 뭔가 일을 해결할 것 같은 느낌입니다. How도 중요하지만 What을 무시하는 것은 아니지만 먼저 생각해보려고 하는 것은 최근인 것 같습니다.
간단히 정리해보면 IoC Container도 객체를 생성하고 삭제하는 것을 라이브러리 이용하는 것처럼 쉽게 “대신” 해주는 녀석
DI Patten도 Interface를 사용했기 때문에 느슨한 결합상태가 되었고(특정 하나의 class로 강제하지 않기 때문) 이 인터페이스를 사용하는 객체가 올 거라고 의존성 주입이라는 어려운 말을 써서 “미리” setting 된 Interface를 사용 할 수 있는 이런 부분들로 생각합니다.
위 내용만 봐도 How에 대한 생각들로 꽉 차있습니다. What이라고 하면 그냥 개발자 편하려고 대신해주는 녀석 만들고 Interface를 사용 해서 협업이 가능하게 하는 구조로 개발하려는 것 같습니다. 즉 개발자 편하게 뭔가 생성해 내고 여러 명이 같이 유지보수 할 수 있는 구조를 정해서 결국 개발자 편하려고 밖에 what은 모르겠습니다. 어떻게 해야 더 편한 건지 또는 명확한 건지는 관련된 경험이 부족한 것 같습니다.
'Computer Science > 소프트웨어 공학' 카테고리의 다른 글
| Interface와 Application 제작 2 (0) | 2021.02.22 |
|---|---|
| Interface와 Application 제작 1 (0) | 2021.02.22 |
| Domain Model vs DTO (0) | 2019.02.28 |