728x90
생성
JPA
- EJB 엔티티빈(사용 어려움)이 등장 후 하이버네이트가 나왔고, 표준으로 JPA가 됨
- JPA는 표준 인터페이스이고 구현체로 하이버네이트, EclipseLink 등이 있음
스프링
- 로드 존슨
- EJB의 문제점 지적 후 생긴 기술
스프링 프레임워크
- 핵심 기술: 스프링 DI 컨테이너, AOP, 이벤트, 기타
- 좋은 객체 지향 애플리케이션을 개발할 수 있게 도와주는 프레임워크
- 웹기술: 스프링 MVC, 스프링 WebFlux
- 데이터 접근 기술: 트랜잭션, JDBC, ORM 지원, XML 지원
- 기술 통합: 캐시, 이메일, 원격접근, 스케줄링
- 테스트: 스프링 기반 테스트 지원
- 언어: 코틀린, 그루비
스프링 부트
- 스프링을 편하게 사용할 수 있도록 지원
- 단독으로 실행할 수 있는 스프링 애플리케이션을 쉽게 생성 (톰캣 내장)
- 손쉬운 빌드 구성을 위한 starter 종속성 제공 (AOP, Data-JPA 등 알아서 라이브러리 땡겨옴)
- 스프링과 3rd party(외부) 라이브러리 자동 구성
- 모니터링 해줌
객체 지향 프로그래밍
- 역할(인터페이스)과 구현(구현한 클래스, 구현 객체)을 분리하면 유연해지며, 변경도 편리해짐
- 객체는 협력이라는 관계부터 생각 (혼자 있는 객체는 X)
- 클라이언트: 요청, 서버: 응답
- 다형성: 클라리언트를 변경하지 않고, 서버의 구현 기능을 유연하게 변경할 수 있음
실습 - 비즈니스 요구사항과 설계
- 비즈니스 요구 사항 설계시 회원 저장소가 미정된 상태로 우선 개발 진행
- 역할과 구현을 나눠서 인터페이스를 만들고, 구현체를 언제든지 갈아 끼울 수 있게 만들어야 함
- 실습은 스프링 사용 없이 개발 진행
1. 회원 도메인
설계
1. 전체적인 도메인 그림
- 역할로써 클라이언트 - 회원 서비스 - 회원 저장소로 분리
- 그중에서 회원 저장소(역할)는 나중에 어떻게 될 지 모르기 때문에 인터페이스로 만들고, 우선 메모리 회원 저장소(컴퓨터 재부팅 시 삭제)로 구현해서 사용 하다가 확정되면 갈아 끼울 수 있게 만듦
2. 클래스 다이어그램
- 정적
- 멤버서비스 인터페이스(역할) 만든 후, 회원 서비스는 회원가입, 회원조회만 하니까 implements 받아서 구현하기
3. 객체 다이어그램
- 동적 (실행했을 때 어떻게 되는지)
- 애플리케이션을 띄워서 동적으로 객체들의 연관관계가 맺어지는 그림
- 클래스 다이어그램으로 알 수 없는 부분 (예를 들어 저장소는 실행 후 동적으로 동작되기 때문에)이 있으므로 실제 실행되는 인스턴스의 설계
개발
- 인터페이스와 구현체를 다른 패키지에 놓는 게 설계상 좋음
- 등급은 Enum, 사용자(멤버)는 class로 만들기
- 역할로 MemberRepository(인터페이스) 만들고 save 저장 기능, findById 조회 기능
- implements 받아서 구현해야하는데 저장소이기 때문에
private static Map<Long, Member> store = new HashMap<>();
//실무에서는 동시성 이슈로 ConcurrentHashMap 써야 함
- 구현체가 없이 null 이면 터지므로 구현체로 MemoryMemberRepository 만들기
실행 및 테스트
package hello.core.member;
import static org.junit.jupiter.api.Assertions.*;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
class MemberServiceTest {
MemberService memberService = new MemberServiceImpl();
@Test
void join() {
//given
Member member = new Member(1L, "memberA", Grade.Vip);
//when
memberService.join(member);
Member findMember = memberService.findMember(1L);
//then
Assertions.assertThat(member).isEqualTo(findMember);
}
}
package hello.core.member;
public class MemberApp {
public static void main(String[] args) {
MemberService memberService = new MemberServiceImpl();
Member member = new Member(1L, "memberA", Grade.Vip);
memberService.join(member);
Member findMember = memberService.findMember(1L);
//제대로 동작한다면 저장한 member == 찾은 findMember
System.out.println(member);
System.out.println(findMember);
}
}
- MemberApp 클래스는 순수 자바코드로 확인
- 문제점
MemberServiceImpl 클래스에서
인터페이스(MemberRepository)는 의존하지만 구현체(MemoryMemberRepository)까지 의존하게 됨
추상화, 구체화 둘 다에 의존 -> DIP 위반 - org.assertj.core.api.Assertions는 메서드 체이닝 지원하기 때문에 문자와 숫자를 비교할 때도 가독성이 좋음
Method chaining 메서드 체이닝
: 하나의 객체에 대해 연속적으로 여러 메서드를 호출하는 것
체인내의 각 메서드는 이전 메서드를 기반으로 동작하고, 다음 메서드를 호출
동일한 객체 참조를 반복하지 않고도 동일한 객체에 대해 여러 어셔션 수행 가능
import static org.assertj.core.api.Assertions.assertThat;
public class ExampleTest {
public void testExample() {
String text = "안녕, 세계!";
// 메서드 체이닝을 사용한 어서션
assertThat(text)
.isNotNull()
.startsWith("안녕") //시작이 "안녕"인가?
.endsWith("세계!") //끝이 "세계!"인가?
.hasSize(8); //text 길이가 8인가?
}
}
728x90
'Server > Spring' 카테고리의 다른 글
[인프런] 스프링 핵심원리 - 4. 스프링 컨테이너, 스프링 빈 (0) | 2023.11.16 |
---|---|
[인프런] 스프링 핵심원리 - 2. 주문 할인 도메인 & 3. 새로운 할인 정책 (0) | 2023.11.13 |
[Spring] DAO, VO, DTO, Entity (0) | 2023.06.20 |
[Spring] SpringMyweb 실습(3) - 페이지네이션, 검색 기능 (0) | 2023.02.09 |
[Spring] SpringMyweb 실습(2) - 게시판 구현 (0) | 2023.02.08 |