1. creature 패키지
1-1. Grade Enum
NORMAL과 ENDANGERED 속성을 만든다.
1-2. Creature 클래스
Creature 클래스를 만든다. 이 클래스는 필드로 id, name, grade를 갖는다. 생성자와 getter, setter를 만들어준다.
2. Repository
생물들에 대한 정보를 저장할 수 있는 Repository를 만든다. 원래는 Database에 Table을 만들어 정보를 저장하는데, 해당 강의에서는 다루지 않는 범위이므로 여기서는 Map 객체로 메모리 저장소를 만든다.
인터페이스 정의
interface 형태로 creatureRepository를 만든다. 생물들의 정보를 저장할 수 있는 save, 조회할 수 있는 findById 메소드를 만든다.
위에서 만든 interface를 상속하는 구현체를 만든다. 우선은 동물들에 대한 저장소로, CreatureRepositoryAnimals라는 구현체를 만든다.
CreatureRepository를 implements로 상속받고, 각 메소드를 오버라이드 해준다.
HashMap<>()을 static으로 정의해서, 컴퓨터의 메모리 공간을 저장소로 정의한다. Database를 사용하지 않는 임시적인 방법이다.
* 원래는 동시성 이슈에 의해 HasMap<>()을 사용하면 안되고, ,ConcurrentHashMap<>()을 사용해야한다고 한다. 해당 객체에 여러 쓰레드에서의 동시 접근이 있으면 정보 저장에 문제가 생긴다고 하는데, 추후에 공부해보자.
3. Service
인터페이스 정의
Respository와 마찬가지로 인터페이스부터 정의한다. 서비스의 기능은 repository를 통해서 생물의 정보를 메모리에 새로 등록하고, 조회할 수 있는 것이다. 각각 register(Repository 에서의 save와 연결), findById(Repository에서의 findById와 연결)로 표현하였다.
여기서 보면, Service 코드에서 repository의 메서드를 사용하기 위해서 private final creatrueRepository... 로 Repository 코드를 불러오는 것을 알 수 있다. 이런 것을 "Service 코드는 Repository 코드에 의존한다." 라고 표현한다. 나중에는 직접적으로 의존관계를 주입받고, "의존관계를 주입받는다."고 표현할 것이다. 일단은 이런 구조라는 것에 유의하자.
4. Test
4-1. main 메서드로 간단히 테스트
앞서 만든 코드가 잘 작동하는지 검사해야한다. main package 내에 CreatureApp.class를 하나 만들고, 아래와 같이 테스트 한다.
다시 정리하자면, 정보를 저장하고 접근할 수 있는 Repository를 만들었고, Repository를 논리적으로 활용할 수 있는 Service를 만들었다. 클라이언트는 Service에 접근해서 repository를 통해 정보를 조회, 생성, 수정, 삭제(CRUD)하는 구조임을 이해하고 있어야 한다.
보통 Repository, Service 그리고 아직 작성하지 않은 Controller에 대해서 따로 테스트를 하지만, 해당 예제는 간단하므로 service, repository를 한 번에 테스트해본다.
creatureService 인터페이스를 선언해서 service를 테스트한다. 여기에 CreatureServiceImpl 구현체를 할당해서 구현체 내에 정의한 메서드를 활용한다는 것을 기억하자. 그 외에 creature1을 만들고 repo.에 저장하고, 저장된 결과를 repo.에서 조회해서 이름값을 확인해보는 구조는 쉽게 이해할 수 있다.
이렇게 main 메서드를 통해서 앱을 실행하는 방법도 있지만, 한계점이 많아서 보통은 Test 프레임워크인 jUnit을 사용한다.
4-2. jUnit으로 테스트
Test package 내에 creature 패키지를 만든다. 해당 패키지 내에 service를 테스트하기 위한 클래스 파일을 만든다.
작성되는 구조는 4-1. main 메서드로 테스트와 같다. 우선 테스트를 할 service 구현체를 불러오고, @Test 어노테이션 아래에 테스트할 내용을 적는다. 여기서 //given, //when, //then 부분은 논리적으로 테스트할 내용을 구분하기 위한 단순 주석이다. 보통 이렇게 구분해서 논리적으로 헷갈리지 않게 한다.
기본적인 코드 작성법과 구조에 대해서 공부했다. 다음편에서는 이런 구조가 갖는 문제점과 해결방안에 대해서 공부한다.
참조
1. 인프런_스프링 핵심 원리 기본편_김영한 님 강의
www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard
'Programming-[Backend] > Spring' 카테고리의 다른 글
[스프링 기초] 6. 사용영역과 구성영역 나누기로 SRP, OCP, DIP 원칙 실현하기 (0) | 2021.06.06 |
---|---|
[스프링 기초] 5. 예제만들기2 : SRP 원칙 및 객체 주입, 의존에 대한 이해 (0) | 2021.06.06 |
[스프링 기초] 3. 프로젝트의 구조 및 생성 (0) | 2021.05.25 |
[TIL] BeanUtils.copyProperties, 엔티티 객체 복사하기 (0) | 2021.05.25 |
[스프링 기초] 2. 객체 지향 프로그래밍의 특징. 자바 스프링 (0) | 2021.05.13 |