이번에는 회원 서비스 클래스를 만들어보자.
회원 서비스는 회원 도메인과 레포지토리를 활용하여 실제 회원들이 사용할 비지니스 로직을 작성하는 것이다.
먼저 java에 service라는 package를 만들어준다. 그리고 service 패키지에 MemberService 클래스를 생성한다.

회원 서비스는 회원 레포지토리를 활용하기에 먼저 만들어놨던 MemoryMemberRepository 객체를 선언한다.
public class MemberService {
// MemoryMemberRepository 객체 선언
private final MemberRepository memberRepository = new MemoryMemberRepository();
}
회원가입은 Member 객체를 Repository에 저장하는 기능이다. 따라서 memberRepository에서 구현해놓은 sava 기능을 호출한다.
회원가입시 id를 반환하는 기능을 가지고있다고 가정하였다.
public long join(Member member){
memberRepository.save(member);
return member.getId();
}
요구사항 정리시 중복 아이디는 회원가입 할 수 없는 항목이 있었다.
findByName을 통해 member의 이름을 result에 담는다.
Optional에서 제공하는 ifPresent()를 사용하여 result에 같은 이름의 회원이 존재한다면 IllegalStateException 에러를 던진다.
여기서 ifPresent()란 Optional 객체이 값이 있다면 뒤의 로직을 실행하는 함수이다.
// 같은 이름이 있는 중복 회원 X
Optional<Member> result = memberRepository.findByName(member.getName());
result.ifPresent(m -> {
throw new IllegalStateException("이미 존재하는 회원입니다.");
});
memberRepository.save(member);
위의 코드를 아래와 같이 개선하였다.
findByName으로 받은 값에 바로 ifPresent를 붙여서 사용하고, return값이 Optional이기 때문 생략하여서 코드를 단순하게 만들었다.
// 같은 이름이 있는 중복 회원 X
memberRepository.findByName(member.getName())
.ifPresent(m ->{
throw new IllegalStateException("이미 존재하는 회원입니다.");
});
메서드는 하나의 행동만 들어있는것이 좋기 때문에 중복 확인 부분을 다른 메서드로 분리하여 구현해주었다.
public long join(Member member){
validateDuplicateMember(member); // 중복 회원 검증
memberRepository.save(member);
return member.getId();
}
private void validateDuplicateMember(Member member) {
memberRepository.findByName(member.getName())
.ifPresent(m -> {
throw new IllegalStateException("이미 존재하는 회원입니다.");
});
MemoryMemberRepository에서 모든 회원 정보를 받는 findAll을 만들었기에 간단하게 findAll을 return 해준다.
// 전체 회원 조회
public List<Member> findMembers(){
return memberRepository.findAll();
}
멤버의 Id를 전달 받아 해당 Id를 갖고있는 객체를 받아서 return 해준다.
public Optional<Member> findOne(Long memberId){
return memberRepository.findById(memberId);
}
회원 레포지토리와 회원 서비스 두 개의 클래스를 만들어 보았다.
두 클래스의 메서드 명을 비교해보면 다른점이 있다.
레포지토리 클래스 내에서는 개발자가 보기 직관적인 느낌의 이름을 사용하는 반면, 서비스 클래스 내에서는 비즈니스에 가까운 용어들을 사용하였다.
이러한 이유는 추후에 유지보수가 용이하게 하기 위함이고
앞으로 클래스 내에 메서드 이름을 정할때 꼭 기억하고 적용하자.