[To do List] 서비스 구현

oh_eol·2024년 1월 23일
0

To-do-List

목록 보기
4/5
post-thumbnail

전체 패키지 구조

전체 패키지 구조는 다음과 같다.

다음 8가지 기능을 구현하기 위해 서비스 코드에 메서드 시그니처들을 정리한다.

  1. todo 리스트 목록에 아이템 추가
  2. todo 리스트 전체 목록 조회
  3. todo 리스트 목록 중 특정 아이템 조회
  4. todo 리스트 목록 중 특정 아이템 수정
  5. todo 리스트 목록 중 특정 아이템 삭제
  6. todo 리스트 전체 목록 삭제
  7. 로그인
  8. 회원가입

Service

TodoService

package todolist.service;

import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import todolist.dto.TodoRequest;
import todolist.dto.TodoResponse;
import todolist.entity.TodoEntity;
import todolist.repository.TodoRepository;

@Service
@RequiredArgsConstructor
public class TodoService {
    private final TodoRepository todoRepository;

    @Transactional  // 하나의 작업 단위를 명시하기 위한 어노테이션이라는 점이 default. 하나는 성공하고 하나는 실패하는 경우 이 작업이 실패라는 뜻이다.
    public TodoResponse create(TodoRequest request) {
        TodoEntity instance = new TodoEntity(request.getTitle());
        TodoEntity todoEntity = todoRepository.save(instance);

        return new TodoResponse(todoEntity);
    }

    @Transactional
    public TodoResponse update(Long id, TodoRequest request) {
        // 업데이트 하려는 todo객체 찾기_id 값으로 조회가 되지 않으면 에러를 내보낸다.
        TodoEntity todoEntity = todoRepository.findById(id)
                .orElseThrow(()-> new IllegalArgumentException("잘못된 입력입니다."));
        // 업데이트 한 투두를 담기
        TodoEntity updatedTodo = todoEntity.update(request.getTitle());
        // 응답하려는 객체에 담아서 반환하기.
        return new TodoResponse(updatedTodo);
    }

    @Transactional
    public void delete(Long id) {
        todoRepository.deleteById(id);
    }

    @Transactional
    public TodoResponse get(Long id) {
        // id 값으로 조회가 되지 않으면 에러를 내보낸다.
        TodoEntity todoEntity = todoRepository.findById(id)
                .orElseThrow(()-> new IllegalArgumentException("잘못된 입력입니다."));

        return new TodoResponse(todoEntity);
    }

    @Transactional
    public Page<TodoResponse> getAll(Pageable pageable) {
        // pageable로 todo를 조회
        Page<TodoEntity> todoEntities = todoRepository.findAll(pageable);

        // entity를 그대로 반환하지 않고 한 번 감싼다.
        Page<TodoResponse> todoResponses = todoEntities.map(TodoResponse::new);

        return todoResponses;
    }
}

MemberService

package todolist.service;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import todolist.entity.MemberEntity;
import todolist.repository.MemberRepository;

import java.util.List;
import java.util.Optional;

//@Service
public class MemberService {
    private final MemberRepository memberRepository;

    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    // 회원가입
    @Transactional
    public String join(MemberEntity memberEntity) {
        validateDuplicateMember(memberEntity);
        memberRepository.save(memberEntity);
        return memberEntity.getId();
    }

    @Transactional
    private void validateDuplicateMember(MemberEntity memberEntity) {
        memberRepository.findById(memberEntity.getId())
                .ifPresent(m -> {
                    throw new IllegalStateException("이미 존재하는 회원입니다.");
                });
    }


    // 회원 조회
    @Transactional
    public Optional<MemberEntity> findOne(String memberId) {
        return memberRepository.findById(memberId);
    }

    // 전체 회원 조회
    @Transactional
    public List<MemberEntity> findMembers() {
        return memberRepository.findAll();
    }

}

ServiceConfig

package todolist.service;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import todolist.repository.MemberRepository;
import todolist.repository.MemoryMemberRepository;

@Configuration
public class ServiceConfig {

    @Bean
    public MemberService memberService() {
        return new MemberService(memberRepository());
    }

    @Bean
    public MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }
}

Test

MemberServiceTest

package todolist.service;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import todolist.entity.MemberEntity;
import todolist.repository.MemberRepository;
import todolist.repository.MemoryMemberRepository;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;

class MemberServiceTest {

    MemberService memberService;
    MemberRepository memberRepository;

    @BeforeEach
    public void beforeEach() {
        memberRepository = new MemoryMemberRepository();
        memberService = new MemberService(memberRepository);
    }

    @AfterEach
    public void afterEach() {
        memberRepository.clearStore();
    }

    @Test
    void 회원가입() {
        MemberEntity memberEntity = new MemberEntity();
        memberEntity.setId("ohohoh");
        memberEntity.setPw("ohoh123");

        String saveId = memberService.join(memberEntity);

        MemberEntity findMember = memberService.findOne(saveId).get();
        assertThat(memberEntity.getId()).isEqualTo(findMember.getId());
    }

    @Test
    public void 중복_회원_예외() {
        MemberEntity memberEntity1 = new MemberEntity();
        memberEntity1.setId("member1");
        memberEntity1.setPw("member123");

        MemberEntity memberEntity2 = new MemberEntity();
        memberEntity2.setId("member1");
        memberEntity2.setPw("member123");

        // member1 을 가입시키고
        memberService.join(memberEntity1);
        // member2 의 중복 여부를 체크
        IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(memberEntity2));
        assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");

    }

}
profile
공부 중입니다.

0개의 댓글