인터페이스와 어플리케이션 제작 1에 이은 내용이다

1탄과 마찬가지로 아래 글에서 시작한다

  • (https://www.slipp.net/questions/21 - 어플리케이션 개발은 어떤 순서로 하면 좋을까?)
  • 1탄에서 언급된 컨트롤러 드리븐은 아래의 방식을 취한다
    1. Controller 개발
    2. Business Layer Interface 도출 (Operate Contract)
    3. Business Layer Concreate Class 구현 (Data Access and Biz Layer)
    4. Persistence Layer Interface 도출 (Data Contract)

어플리케이션 개발은 어떤 순서로 하면 좋을까?

이에 대한 윗 글속의 자바지기 님의 순번을 매겨보면 아래와 같다

  1. 중심이 되는 도메인을 설계한다. (Model Class –> business Model)
    • 필수로 쓰이는 개념을 가지고 클래스로 생각하고 연관 클래스 모델과 Package 구조를 잡는다 (모델 설계)
  2. 클래스 구조를 잡은 후 속성들을 하나씩 채워 나간다. (column or property) (모델의 속성 설계)
    • 물리적인 데이터 베이스와 매핑은 하지 않은 상태이기 때문에 기본적인 뼈대와 속성 추가에만 집중하며 전단계의 모델 설계가 개념적 모델링에 가깝다면 지금 단계에서는 논리적 모델링으로 접근한다
  3. 만족할만한 수준으로 뼈대가 완성되면 이때부터 데이터베이스에 대한 매핑 정보를 추가하고 Repository를 구현한다 (DAO or DA의 기초 interface)
    • Repository가 Spring Data JPA를 사용하고 있다면 상관없고 그렇지 않다면 Entity(Model)에 기본적인 CRUD 기능이 가능한 상태로 만들어 준다

그 다음에

  1. Controller를 추가하고 View와 연관지어 사용자 관점의 화면 흐름을 구현하고 테스트한다 (Controller 에서 Business를 구분)

  2. 이 과정을 마친 후에 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를 통한 협업이나 느슨한 의존성 또는 재활용 관점이나 확장에 유연하고 변경에 엄격하게 유지보수를 할 수 있는 방법을 고민하지 못했다는 자아성찰 및 반성이 되는 글이었다

자바지기님 정도의 내공을 가진 사람도 interface에 대한 Input과 Output 보다 내부 구조부터 고민하는 것을 보니 시간이 지나고 실력이 늘어도 더 좋은 방법이라는 고민은 쉽게 풀리지 않는 구나 라는 생각이 들었다

아무래도 정답이 없는 것에 대한 고민은 개발자가 평생 겪는 고민 같은 것이고 만약 나의 답을 내려도 시니어가 되었을 때 내 답만 고집하게 될 수도 있을 것 같다는 생각도 들었다 (개발자도 확장에 열려있어야 한다)

좋은 기준을 정한다는 게 누구나 겪는 쉽지 않은 고민이라는 부분이 눈에 띄었다

댓글의 토론에서 C기반의 헤더파일을 인터페이스에 비유하는 부분이나 그렇기 때문에 헤더파일에 Function을 추가하는 거랑 Interface/Class 에 Method를 추가하는 것에 대한 차이를 논하는 것은 참신하게 놀라웠다

결과적으로는 문법적인 영역으로는 검증이 불가능한부분 이라고 말하고 있지만 개념적으로는 비슷한 부분이 있다고 생각되었다

Object(Class) != Structure + Function 
요즘 OOP에서 강조하는 부분은 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 설계 경험이 있어야 한다

"Facebook API 고쳐주세요!"하면 "있는 걸로 하세요. 다음 버전에는 고려해 볼께요." 라는 이야기가 나오는게 정상이지

 "고객님 죄송합니다. 바로 고쳐 드릴께요."라고 할 리가 없다고 봅니다

이 부분이 너무 찔리고 있다….

초기 개발 수준에는 Interface의 역할에 대한 이해 조차 없다고 봐야겠다

그냥 비슷한데 결과만 다른 메소드 하나 추가하면 저런 요구사항은 구현으로는 누구나 할 수 있다

하지만 변화가 발생했을 때

어디까지 영향이 가는지 그리고 이런 예측이 힘들면 새로 만드는 명함만 개발자들의 특성상 1:1 매칭되는 클래스나 인터페이스나 메소드나 이런류의 결과가 계속 나오게 되는 것이다

이런 부분의 1:1로 개발하는 이유가 전체 구조에 대한 고민은 적게하고 당장 요구한 부분만 고민을 하면서 개발이라는 흉내를 내기 때문이다

요구사항만 들어주면 되고 내부 구조는 갉아먹고 있었던 것이다……

근데 진짜 고민했는데도 기존 구조상에서 좌절해서 포기해서 어쩔 수 없이 1번 2번 숫자 네이밍 달린 매소드를 만들 때 (전체적으로 바꿔야 하는 10년이상의 시스템에서) 이를 방지하려면 처음부터 고민해서 잘 만들어 나가야 한다

일단 만들고 나중에 리팩토링도 가능하겠지만 이는 능력자들의 고려대상 이고 보통의 개발자라면 충분히 고민하고 품질관리가 무었인지 알고 품질이라는 것은 제조업의 QC, QA가 아니라 SW에서 충분히 보증서가 된다는 것을 몸소 느끼는게 성장하는 방향이 맞다고 본다(어디가 좋은 회사이지? 이런 것을 결정할 수 있는 이유로도)

결론이 기술적인 탐구보다는 반성이 되었는데 이게 과거에 썼던 글이고 처음으로 SW 개발을 어떻게 해야 좋은 방법이지? 라는 의구심의 시작이었던 것 같다

그래도 고쳐쓰면서 다시 한번 새롭게 시작할 수 있었던 것 같다

참고된 글을 몇개 더 남기자면

위 연관 시리즈에서 맨 처음 보게된 글이었고 여기서 든 생각은 계층과 계층간에 data를 주고 받을 때 DTO를 사용할 것이며 그 DTO안에는 DB로부터 얻은 결과 or Business Model 들을 가지고 있다 라는 생각이다

그리고 지금은 DTO를 여러개 만들기 보다는 DA나 Biz에서 사용하는 Model들을 내부 Method를 통해 Builder 형태나 Static Method를 통해 생성시키고 모델 내부에서 비즈니스 변경을 처리하는 구조로도 개발 해보고 있다

마지막으로 고민해봐야 하는 내용이 있다

Java를 만든사람들이 보기에, Object-oriented Programming 은 "How" 보다는 "What"에 초점을 맞추고 있다고 합니다. 여기서 대명사처럼 쓰인 Java는 OOP라는 개념으로 생각됩니다.
전체 개발 과정에서 "What(Domain)"에 관심을 가지면, Interface 설계는 자동으로 따라오는 거라고 봅니다. 
결론은 정상적인 Domain 설계는 Interface 설계를 포함하고 있다고 한다 (1탄의 명사와 동사의 관계와 비슷한 느낌이 있다) 
Method 들의 Set(집합) 으로 Domain이 겪어야 할 Method를 같이 설계에 넣어야 하는 것이라면 CRUD도 Interface 설계의 일부분이다  

이제 최종적으로 내가 이 글을 쓰면서 생각하게 된 Application(why) 개발에 대해 남긴다

글쓰기는 그렇지 않지만 프로그래밍에서는 항상 How(구현이)가 생각난다

How를 생각하면 일정도 산정할 수 있을 것 같고 문제를 푸는 기분으로 뭔가 일을 해결할 것 같다

이 당시 Spring을 사용하지 않기에 .Net에 기반에서는 IoC Container는 객체를 생성하고 삭제하는 것을 쉽게 “대신” 해주는 라이브러리로 사용하는 녀석이고

DI Patten도 Interface를 사용했기 때문에 생성과 사용에서 느슨한 결합상태가 되었고(특정 하나의 class로 강제하지 않기 때문) 이 인터페이스를 사용하는 객체가 올 거라고 의존성 주입이라는 어려운 말을 써서 “미리” setting 된 Objcet를 적시적소에 사용 할 수 있는 부분들이었다

위 내용을 보면 Why 이런걸 사용해야 하지?? 라는 생각보다 이걸 어떻게 구현하거나 사용해야 하지? 와 같은 How에 대한 생각들이 먼저 되었다

달라져 보기로 했으니 보편적인 언어로 다시 고쳐써 본다면

여기서 why를 먼저 생각한다는 것은 개발자가 현재 Coding 하는 것이 과거와 비교해서 더 편해 보려고(레거시 프레임워크) 대신해주는 녀석을 새로 만들게 되었고

유지보수 할 때 Interface를 사용해서 변경에 종속되는 것이 아니라 느슨하게 결합되어

관심사에 따라 Interface가 분리되어 업무에 따른 다른 사람의 수정사항에 대해 영향을 받지 않고 다른 개발자와 Interface로도 협업이 가능하게 하는 구조로 개발하는 것이 되었다

즉, 구현에 전전 긍긍하고 쫄리기 보다는 어떻게 하면 개발자 편하게 뭔가 생성해 내고 여러 명이 같이 유지보수 할 수 있는 구조를 정할 수 있지??

단순한 규칙을 정해서 복잡하지 않고 누구나 쉽게 개발에 접근할 수 있는 것을 어덯게 만들지??

이런 접근 방법이라면

  1. Application 개발도 결국에는 개발자가 편한 구조가 되야 하고

  2. 변경에 대한 영향도가 없고 확장이 쉽게 개발하는 접근이 되야 하며

  3. 새로운 것을 도입하거나 기존방법에서 변경사항이 생길 때에도 이걸 왜 해? 질문을 하고 대답할 수 있어야 한다

이 결과물과 고민이 더 편한 Application 개발을 할 수 있는 것이라면

한 문장의 결론 : Interface를 통해 OOP 개발을 하는 것은 이것을 이용하는 것이 
라이브러리의 활용이나 개발 방법에서 기존의 개발방법 보다 더 편하고 생산적인 Application 구조가 되기 때문에 
더 좋은 SW 만드는 것이 가능하기 때문에 잘 활용할 수 있어야 한다    

하지만 정답은 없다고 본다. 다만 지금의 생각이 나중에 새로운 걸 접했을 때 머물지 말고 더 발전되길 바란다

'Computer Science > 소프트웨어 공학' 카테고리의 다른 글

Interface와 Application 제작 1  (0) 2021.02.22
Domain Model vs DTO  (0) 2019.02.28

초안은 2018년도에 내 마음대로 작성한 글인데 그때보다 지금의 지식으로 정제하기 위해 고쳐쓰기로 마음먹었다

이 글 본문을 읽기 전에 먼저 VO vs DTO vs DAO vs Domain Model 을 구분할 수 있는지 가슴에 손을 얻고 생각해 봐야할 것 같다

이 글을 적으면서 Fix 하려고 하는 개념이지만 이게 진짜 맞을까? 라는 의심 한구석이 생겨나고 있는데 일단 너무 개념과 용어에 매몰되어 바보가 되진 말자

먼저 객체에 대해 개념 그룹핑을 한다

  1. Data Object

    1. VO
    2. DTO
  2. Entity Object

    1. Domain
    2. Database Table
  3. Imutable Object

    1. VO
  4. Data Access Object

    1. 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 챕터를 만든다면 추가 적으로 얘기하겠다

본론으로 돌아와서 제목에 관련된 토론을 시작하게 된 글과 함께 시작해보자

흥미로운 부분은 비즈니스 레이어에 외부와 협업이 있으면 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

http://hankkuu.egloos.com/category/Data%20Structures

http://www.hani.co.kr/arti/economy/it/866949.html

내 수준에 독자적인 글을 쓰는게 매우 어렵다. 사실 블로그도 한다는게 매우 어렵다는것을 느끼고 있다.. (이러다 지치지 않을까??)

어쨌든 카카오톡 오픈채팅에서 개발자관련 페이지를 마구등록하다 몇몇 괜찮은 것들이 추려져서 그 글과 관련된 내용을 가지고 조금씩 다시 개선된 블로그 활동을 해보려고 한다.  

먼저 가져온 글은 http://toby.epril.com/?p=99 이다  

모델을 어떻게 만들고 어떻게 활용하는 것과 같은 문제는 매우 중요하기에 해당 글을 가지고 시간 될 때 다루어 보기로 한다 

'Computer Science > 소프트웨어 공학' 카테고리의 다른 글

Interface와 Application 제작 2  (0) 2021.02.22
Interface와 Application 제작 1  (0) 2021.02.22

+ Recent posts