부트캠프/항해+99 백엔드

태태개발일지 - TDD & CleanCode

태태코 2024. 6. 30. 13:22
반응형

 

- TDD

2주동안 처음 배우게 된 부분은 TDD 즉 TC(Test Code)를 짜는 방법과 그 이유였다.

간단하게 내가 습득한 내용에 대해서 정리해 보겠다. 

 

TDD: 
      요구사항을 분석한 후 실제 비지니스로직을 작성하고 그에 맞는 TC를 작성하는 순서가 아닌  요구사항을 분석하고 바로 TC를 통해서 요구사항을 적용해 나가는 방법.

TDD를 통해서 실패하는 TC들을 성공하는 케이스들로 바꾼후, TC에 따라서 실제 비지니스 로직 코드를 변경하는 사이클을 가지고 

한 사이클이 끝나면, 그 코드들을 Clean code와 객체지향을 도입하여 리펙토링 하는 과정이다.

 

TDD를 통해 얻을 수 있는 이점:

    TestCode를 짤때는 가장 작은 단위부터 작성하고 테스트해야하기 때문에 

1. 하나의 클래스에 너무 많은 로직을 담지 않고 적절하게 역할을 분리하게 된다.

2. 주구장창 로직을 작성하지 않고, 어떤 역할을 하는 클래스들이 구조화되어야 하는 지 미리 고민하게 되었다. 테스트 코드를 먼저 작성하려면, 어떤 클래스들이 있고, 각 클래스가 무슨 역할을 해야할 지 미리 생각해봐야 테스트코드 작성완료

 

"개발해야되는 스코프가 점점 더 많아지고 거대한 규모의 소프트웨어가 많아짐에 따라, 유지보수 및 장애 발생시 대처를 유연하게 할 수 있는 방법론으로 다들 회귀하기 시작했습니다. 즉, 코드의 규모는 점점 커지고 유저가 많아짐에 따라 예측하기 힘든 행동 패턴들에 의한 장애가 발생하기 시작한 거죠. 소위 새로운 기능을 만들기 위해 “요구사항을 찍어낸다” 식의 단순 재래식 개발로는 소프트웨어의 품질을 지속적으로 유지하고 향상시킬 수 없었기에 테스트 자동화에 대한 중요성은 점점 대두되어 왔습니다. 요구사항이 변경되었을 때, 기존의 기능이 영향이 없는가? 등을 검증하기 위한 방법론들이 주목받지 못하고 있다가 빠른 변화에도 유연하게 새로운 기능을 적용하고 변경할 수 있는 기반을 다질 수 있는 TDD 에 대한 중요성이 더욱 더 중요해지고 있습니다."

-항해 +

 

간단하게 기능 요약

Controller Test - Controller -> MockMvc 로 단위테스트만 짬 = API Spec 을 점검하는게 목적
Service -> 서비스 짬 = 단위 테스트 (비지니스 로직 테스트)

Repository Interface 짬.

Infrastructure ( RepositoryImpl 짬 ) = 통합테스트

 

- Clean Layerd 아키텍쳐

 

/interface(or api pr controllr)

   - controller

/application(facade)

   - facade

/domain

  -entity

  - service

  - repository

/infrastructure

   - repositoryImpl

 

가장 기본적인 Clean Layerd 아키텍쳐이고,

이는 단방향 참조 -> 하향식 참조이다.

 

이렇게 하는 이유는 양방향일 때 서로 참조를 하면 서로의 코드가 영향을 주기 때문에 상위 계층에서 하위 계층을 참조하게 하기 위함이다.

여기서 domain에 DIP(의존성 역전)을 사용하여 repository(interface)를 두어서 infra의 repository랑 분리한 이유는

 

domain이 가장 중요한 부분이여서 이를 보호하기 위해서 interface -> domain <- infra 이렇게 의존성을 꺾어준 것이다.

이를 통해서 domain이 infra의 interface를 보게되어 실제 구현을 모르게 된다.

실제 거의 모든 회사에서 이 아키텍쳐를 선호한다고 알게되었다.


그리고 service와 serviceimpl로 나누어서 구현하는 방식도 있는데.
service 의 명세와 구현이 다양화되잇을 수 있는 예예를 들어 UserService / AdminUserService , ApiUserService  같은 형태일  유의미해집니다.

또한 Api에서 필요한 각 기능을 Usecase 형태의 인터페이스로 만들고, 서비스가 이를 모두 구현(Impl) 해 구현을 미루는 방식도 있으나, 이는 비지니스의 구현이 뒤로 미뤄지는 방향이라 선호하지 않는다.

 

또한 일반적인 서비스 구조에서는 서비스 - 서비스 구현체가 1대1 구조라 잘 사용하지 않는다.

clean 아키텍쳐보다 알게된사실은

Service단은

save(long id){

---> 객체가 직접 역할 수행 entity = findbyId(id);

entity.bark();

save(entity)

}

 

그저 repository의 사용을 위해 사용하고 실제 객체 지향과 DDD를 구현하기 위해 객체가 직접 행동할 수 있게 domain쪽에 간단한 비지니스 로직을 넣는게 좋다는 것을 알 게 되었다.

 

 

반응형