블로그
전체 6#카테고리
- 백엔드
#태그
- 워밍업클럽4기
- 클린코드
- 발자국
- 백엔드
- SOLID
- 객체지향
- 추상
- 구체
2025. 06. 17.
0
워밍업 클럽 4기 BE 클린코드 & 테스트 < Day16 미션 - 레이어드 아키텍처 >
MissionLayered Architecture 구조의 레이어별 테스트 작성법을 알아보았습니다.레이어별로 1) 어떤 특징이 있고, 2) 어떻게 테스트를 하면 좋을지, 자기만의 언어로 다시 한번 정리해 볼까요? Persistence Layer역할: DB와 직접 연결되는 레이어. JPA, QueryDSL 등을 활용해 CRUD와 복잡한 쿼리를 처리함.테스트 방법:@SpringBootTest 또는 @DataJpaTest를 사용해 통합 테스트 진행.Repository 단독 테스트가 대부분이라 단위 테스트처럼 가볍게 돌릴 수 있음.주의사항:쿼리 변경이나 추가가 자주 발생하므로, 쿼리 하나당 테스트 하나 작성하는 습관 필요. Business Layer역할: 비즈니스 로직 중심. Service가 핵심이며 트랜잭션(@Transactional) 관리가 중요.Presentation으로부터 받은 데이터를 가공하거나 Validation, 상태 변경 등을 수행.테스트 방법:@SpringBootTest 사용해 통합 테스트.필요시 @ExtendWith(MockitoExtension.class)로 단위 테스트 가능.테스트 시 불필요한 의존성은 제외하고, 필요한 데이터만 넘겨주는 Builder 패턴 활용.주의사항:서비스 로직 테스트 전에 도메인과 Repository 테스트 먼저 작성.동시성 문제 있는 로직은 멀티스레드 테스트 고려해야 함. Presentation Layer역할: 외부 요청을 받아 내부 시스템에 전달하고, 응답을 반환하는 API 담당.Request 값에 대한 Validation 처리 담당.내부 로직은 갖지 않고 Service에 위임함.테스트 방법:@WebMvcTest(Controller.class) + MockMvc + @MockBean 조합으로 테스트.요청 값 검증, 상태 코드, 응답 구조 확인.ObjectMapper로 직렬화/역직렬화 테스트.주의사항:Request DTO는 Controller용과 Service용으로 분리하는 게 확장성에 좋음.JSON 역직렬화를 위해 기본 생성자와 getter 꼭 필요.비즈니스 로직 관련 검증은 Service에서 처리하고, 이 레이어에선 최소한의 검증만 수행.
2025. 06. 15.
1
워밍업 클럽 4기 3주차 발자국
3주차 강의 내용 : Spring & JPA 기반 테스트음, 이번주는 바빠서 강의를 거의 듣지 못했다ㅠㅠ얼른 따라잡아서 4주차 마무리를 잘 해내는 것을 목표로 해야지... 3주차 과제 내용 : 테스트 코드 실습지뢰찾기 게임 코드를 바탕으로 테스트 코드를 작성했다.가장 작은 단위의 메서드부터 테스트를 작성해보려고 했는데, 생각보다 잘 되지 않았다.그래서 클래스에 구현된 메서드의 순서를 따라 테스트를 작성했다.
2025. 06. 08.
1
워밍업 클럽 4기 2주차 발자국(25.06.02 ~ 25.06.08)
한 주 요약객체 지향적 사고를 기반으로 스터디카페 예약 코드 리팩토링하기단위 테스트, TDD에 대해 공부하기 과제 회고이번 주 과제는 스터디 카페 예약 코드를 수업을 듣기 전 내 생각대로 리팩토링 하는 것이었다.Oops...강의를 들었지만 막상 코드를 열어보니 대체 어디서부터 손을 대어야 할 지 감이 잡히지 않았다ㅠㅠ결국 거의 고치지 못하고 제출했지만, 금요일 중간 점검 시간에 다른 분들이 한 코드를 보면서아, 이런 식으로 접근했으면 좋았겠다, 라는 인사이트를 얻을 수 있었다.
백엔드
・
워밍업클럽4기
2025. 06. 01.
1
워밍업 클럽 4기 1주차 발자국 (25.05.26 ~ 25.06.01)
+) 06.02 수정. 타 수강생의 발자국을 보니 제가 너무 자세한 내용을 써서 수정했습니다😁 What I learned?읽기 좋은 코드를 작성하기 위한 초석 다지기추상 & 논리, 사고의 흐름추상의 관점에서 코드를 작성하고, 인지적 경제성을 메모리에 적용해서 최소한의 데이터로 최대한의 효과를 내어야 한다. 즉, 적은 정보를 올리도록 코드를 짤수록 읽기 쉬워진다.추상의 관점에서 생각해 볼 수 있는 것은 이름, 메서드 선언부, 추상화 레벨, 매직 넘버·매직 스트링이 있다. 이것들을 적절히 추상화했을 때 가독성과 유지보수성이 높아진다.데이터는 논리, 사고의 흐름 관점에서 생각해야 한다. 복잡한 if ~ else if ~ else문 대신 early Return을 적용해보자. 중첩 반복문, 중첩 분기문에서는 메서드 추출로 dept를 줄일 수 있다. 길고 긴 로직은 공백을 주어 내용을 가시적으로 구분지을 수 있다. 놓치기 쉬운 부정연산자(!) 대신 메서드 이름 자체에 not 등으로 부정을 표현할 수 있다. 또는 로직의 구성을 변경해 긍정의 이름을 부여할 수도 있다. 예외 상황을 어떻게 처리하는 지도 읽기 쉬운 코드를 위한 방법 중 하나이다. 객체 지향객체는 어떤 목적을 가지고 추상화된 데이터와 코드의 집합이고, 추상의 관점에서 관심사의 분리가 일어난다.객체는 메서드와 마찬가지로 생성된 순간 내부 세계와 외부 세계로 나뉜다. 공개 메서드를 통해서만 내외부 세계간 소통이 가능하고, 객체 내부는 비공개다.관심사가 한 곳에 모이기 때문에 유지보수성이 증가하고, 사용자는 구체적인 구현에는 신경쓰지 않고 도메인 로직을 다룰 수 있다는 장점이 있다.대신 객체마다 1개의 관심사로 명확하게 책임이 정의되어야 한다.또한 외부에서 검증받지 않은 데이터로 바꾸는 것을 지양하기 위해 "Setter"의 사용은 자제해야 한다."Getter"도 필요한 순간에 추가해보자.SOLID는 객체 지향 설계에서 지켜야 할 5개의 소프트웨어 개발 원칙이다.SRP, OCP, LSP, ISP, DIP가 있다. What I solved?한 주간 진행한 미션MISSION 1. 추상추상에 대해 학습하고 실생할에서의 어떤 행동을 추상, 구체로 나눠 표현하는 미션을 실행했다.미션 포스트 : https://inf.run/SNAKB회고그동안 코드에 대해 추상화, 추상화, 말은 많이 했지만 정말 추상적으로만 알고 있었다는 사실을 이번에 깨달았다.미션을 하면서 추상, 구체를 조금 더 명확하게 받아들였고, 코드에 어떻게 적용할 지를 생각해 보게 되었다. MISSION 2. 리팩토링 & SOLID 나만의 언어로 정의하기논리, 사고의 흐름 섹션에서 배운 것을 바탕으로 주어진 코드의 리팩토링을 진행했고,SOLID를 나만의 언어로 정의해보았다.미션 포스트 : https://inf.run/MiB5d회고그동안 리팩토링이라고 하면 이름 변경, 중복 코드 제거 등만 해왔는데, 수업을 들으며 "어떤 것"을 "어떻게", 즉, 리팩토링의 대상과 방법을 구체화하게 되었다. 그것을 반영해서 최대한 "읽기 쉬운" 코드를 만들고자 했다.SOLID를 나만의 언어로 정의하는 것은 쉬운 듯 하면서 어려웠다. 나름 이해하기 쉬운 단어로 표현해보려 했지만 아직 부족하게 느껴진다. 미션은 제출했지만, 이 부분은 면접을 대비해서라도 조금 더 생각해 봐야겠다. END.개인적으로 준비할 일이 겹쳐서 조금 바빴던 한 주였다.수업을 다시 내 것으로 만들어볼 시간이 부족했다.이번 주부터는 부지런하게 공부해보자!
백엔드
・
워밍업클럽4기
・
클린코드
・
발자국
2025. 05. 30.
0
워밍업 클럽 4기 BE 클린코드 & 테스트 < Day4 미션 - 리팩토링, SOLID >
Day4 미션 - 1. 리팩토링 하기✔ 사용자가 생성한 '주문'이 유효한지를 검증하는 메서드.✔ Order는 주문 객체이고, 필요하다면 Order에 추가적인 메서드를 만들어도 된다. (Order 내부의 구현을 구체적으로 할 필요는 없다.)✔ 필요하다면 메서드를 추출할 수 있다.public boolean validateOrder(Order order) { if (order.getItems().size() == 0) { log.info("주문 항목이 없습니다."); return false; } else { if (order.getTotalPrice() > 0) { if (!order.hasCustomerInfo()) { log.info("사용자 정보가 없습니다."); return false; } else { return true; } } else if (!(order.getTotalPrice() > 0)) { log.info("올바르지 않은 총 가격입니다."); return false; } } return true; } 리팩토링한 코드public class Day4 { public boolean validateOrder(Order order) { try { if (order.notExistItem()) { throw new IllegalArgumentException("주문 항목이 없습니다."); return false; } if (order.incorrectTotalPrice()) { throw new IllegalArgumentException("올바르지 않은 총 가격입니다."); return false; } if (order.notExistCustomerInfo()) { throw new IllegalArgumentException("사용자 정보가 없습니다."); return false; } return true; } catch (IllegalArgumentException e) { log.error("주문 검증 중 예외 발생: {}", e.getMessage()); return false; } } } class Order { private List items; private Customer customer; public boolean notExistItem() { // 아이템 있는지 확인하는 로직 return true; // 예시로 true 반환 } public double totalPrice() { // 총 가격 계산 로직 return totalPrice; } public boolean incorrectTotalPrice() { return totalPrice() 중첩 조건문을 분해해서 Early Return을 적용했다.부정어 제거 + 객체 설계. 객체 설계는 섹션3의 내용은 아니지만 함께 적용했다. 부정어를 사용하는 대신 부정의 의미를 나타내는 메서드를 만들고, 해당 메서드는 Order 객체 내에서 처리했다.if문 조건문의 추상화 수준을 같게 설정했다.단순 로그만 찍는 코드에서 예외처리로 변경했다. Day4 미션 - 2. SOLID 나만의 언어로 정의하기SOLID란, 객체지향 설계에서 지켜줘야 할 5개의 소프트웨어 개발 원칙이다. 1. Single Responsibility Principle; 단일 책임 원칙하나의 객체에 하나의 책임만!객체가 갖는 책임이 많아질수록 다른 객체들과의 관계가 깊어지게 된다. 즉, 결합도(의존성)가 늘어난다.결합도(의존성)가 크면 해당 객체의 변경에 따른 영향도와 범위가 커지게 된다.따라서 객체 하나에는 하나의 책임만 부여하여 응집도는 높게, 결합도(의존성)는 낮게 설계해야 한다. 2. Open-Closed Principle; 개방-폐쇄 원칙확장에는 열려있고, 수정에는 닫혀있게.신규 기능이 추가되어야 할 때, 기존 코드의 변경 없이 시스템 확장이 가능하게 설계해야 한다. 3. Liskov Substitution Principle; 리스코프 치환 원칙상속 구조에서, 부모 클래스의 인스턴스를 자식 클래스의 인스턴스로 치환할 수 있어야 한다.즉, 가업승계 하듯이 부모 클래스가 일하던 곳에 자식 클래스가 가더라도 문제가 없어야 한다.자식 클래스는 부모의 모든 책임을 준수하며, 부모 클래스를 변경하지 않아야 한다.만약 LSP를 위반하면, 오동작하거나 예상 밖의 예외가 발생하게 된다. 4. Interface Segregation Principle; 인터페이스 분리 원칙기능 단위로 인터페이스를 분리 설계할 것하나의 인터페이스에 추상 메서드들을 이것저것 구현한다면,그 인터페이스를 상속받은 클래스는 자신이 사용하지 않는 메서드마저 억지로 구현해야 하는 상황이 올 수 있다.이런 불필요한 의존성으로 인해 결합도가 높아지고, 특정 기능이 여러 클래스에 영향을 미치게 된다. 5. Dependency Inversion Principle; 의존 역전 원칙객체들이 서로 정보를 주고 받을 때 의존 관계가 형성되는데, 이 때 하나의 약속이 있다.나(객체)보다 추상화 례벨이 높은 상위 수준의 모듈과 통신해야 한다는 약속이다.의존 역전 원칙은 고수준 모듈과 저수준 모듈 모두 추상화된 인터페이스에 의존해야 한다는 원칙이다.이 원칙을 지키면 저수준 모듈(구현체)가 바뀌어도 고수준 모듈에는 영향이 없다는 장점이 있다.== 결합도가 낮아짐 == 유지보수가 쉬워짐
백엔드
・
백엔드
・
SOLID
・
객체지향
・
클린코드
2025. 05. 28.
0
워밍업 클럽 4기 BE 클린코드 & 테스트 < Day2 미션 - 추상 >
추상 : 물을 마신다구체 레벨로 표현탁자 위의 물의 위치를 인지한다손을 컵의 손잡이로 뻗어 움켜쥔다팔을 들어 컵의 가장자리가 입술에 닿도록 한다손을 움직여 컵을 기울인다흘러나오는 물이 입 속을 채운다식도를 움직여 물을 삼킨다
백엔드
・
백엔드
・
클린코드
・
추상
・
구체