상품 도메인 개발

상품 도메인과 상품 Repository를 구현해본다.

상품 도메인 모델과 요구사항 명세에 따라 구현한다!

  1. 상품 도메인 모델 구현(domain패키지>item패키지>Item 클래스 생성) int가 아닌 Integer로 설정한 이유 : 값이 안 들어가는 경우도 있기 때문에 null값도 받기 위해서다. 단순히 데이터를 주고받는 경우는 사용할 수도 있지만, 다음과 같은 이유로 @Data 애노테이션을 사용할 주의해야한다! (@Getter, @Setter 정도만 사용하는 것을 추천)

    • @ToString의 경우 객체의 양방향 연관관계(a->b,b->a)가 있을 때 무한 루프로 호출될 수 있다.

    • Equals, hashCode도 모든 필드를 다 기준으로 잡는다.

package hello.itemservice.domain.item;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;

@Data
public class Item {
    private Long id;
    private String itemName;
    private Integer price;//price가 안들어갈 때도 있다고 가정하기 때문에 null도 받기 위해서
    private Integer quantity;

    public Item(){

    }

    public Item(String itemName, Integer price, Integer quantity) {
        this.itemName = itemName;
        this.price = price;
        this.quantity = quantity;
    }
}

2. 아이템 Repository 구현(domain패키지>item패키지>ItemRepository 클래스 생성)

멀티스레드 사용하는 실무 환경에서 여러 스레드가 동시에 접근 가능한 동시성 문제와 스프링 컨테이너에서는 객체가 싱글톤으로 생성되기 때문에 HashMap사용하면 안되고 ConcurrentHashMap 사용해야한다. long 변수도 atomiclong 을 사용해야한다!

상품 전체 조회 findAll() : 아이템 객체들 날 것 그대로 반환해도 되지만 값을 변경해도 ArrayList에 값을 넣고 원래 객체 데이터는 보존하기 위해 ArrayList로 한번 감싼다!

상품 수정 update() : id가 사용되지 않기 때문에 updateParam라는 별도의 객체를 생성하는 것이 맞다! 개발자는 혼란스러워서 id필드가 있는데 왜 업데이트가 안되는지 의문을 가지며 setId로 값을 갱신해버릴 수도 있기 때문이다!

package hello.itemservice.domain.item;

import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Repository
public class ItemRepository {
    private static final Map<Long,Item> store = new HashMap<>();//static
    private static long sequence = 0L;//static

    //상품 등
    public Item save(Item item){
        item.setId(++sequence);//@Data가 제공하는 자동 setter 기능으로 눈에 보이지는 않지만 Setter 존재!
        store.put(item.getId(),item);
        return item;
    }
    //상품 조회(id)
    public Item findById(Long id){
        return store.get(id);
    }
    //상품 조회(전체)
    public List<Item> findAll(){
        return new ArrayList<>(store.values());//아이템 객체들 반환
    }
    //상품 수정
    public void update(Long itemId,Item updateParam){
        Item findItem = findById(itemId);
        findItem.setItemName(updateParam.getItemName());
        findItem.setPrice(updateParam.getPrice());
        findItem.setQuantity(updateParam.getQuantity());
    }
    //전체 상품 삭제
    public void clearStore(){
        store.clear();
    }
}

3. ItemRepository 테스트 코드 작성 save() : 상품 생성, ItemRepository에 등록하고 ItemRepository에서 id로 찾은 객체와 같은지 비교. update() : 상품1 생성(itemId), ItemRepository에 등록. 상품2 생성, 상품2로 상품 수정(itemId,item2) 상품1의 iditemIdItemRepository 조회했을 때 상품2의 각 속성 값들과 같은지 비교. (쉽게 말해서 상품1을 상품2로 업데이트했기 때문에 상품1의 id로 상품2의 속성값들로 업데이트되있어야함) findAll() : 상품1, 상품2 생성해서 ItemRepository에 등록, itemReository.findAll() 결과를 리스트에 저장. 리스트의 크기가 상품 갯수와 같은지 비교, 객체 상품1과 상품2를 포함하는지 비교(assertThat(List).contains(item1,item2))

Last updated

Was this helpful?