Java / Spring

Web 기초 설계 본문

Spring/Framwork

Web 기초 설계

밍구밍구밍 2024. 4. 30. 12:58

Spring, Web 개발 기초

 

1. 웹 어플리케이션 계층 구조를 설계 한다.

※ 출처 : (인프런)김영한 님의 SPRING 입문편

(기본적인 어플리케이션 설계 시 컨트롤러, 서비스, 리포지토리, 도메인으로 설계 한다. (*DB 미선정 상태 가정))

 

- 컨트롤러 : 웹 MVC의 컨트롤러 역할

- 서비스 : 핵심 비즈니스 로직 구현

- 리포지토리 : 데이터베이스에 접근, 도메인 객체를 DB에 저장하고 관리

- 도메인 : 비즈니스 도메인 객체, ex ) 회원, 주문, 쿠폰 등등 데이터베이스에 저장하고 관리됨.

 

2. 클래스와 의존 관계

※ 출처 : (인프런)김영한 님의 SPRING 입문편

 

- 아직 DB 미선정으로, 인터페이스로 구현 클래스를 변경할 수 있도록 설계 할 예정이다.

(메모리를 인터페이스를 통해 넣고, 뺄 수 있는 기능)

 

3. 도메인 (domain)

- id 와 name 을 정의할 도메인 Member 클래스 설계 (getter & setter)

public class Member {

    private String name;
    private Long id; // 시스템이 저장하는 id (임의)

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

 

 

4-1. 저장소 (Repository) - Interface 설계 (기능 정의)

- 인터페이스를 설계하고 총 4가지의 기능을 정의 하였다.

 

1) 회원 이름을 저장하는 기능 : save();

2) DB 에서 회원 아이디를 찾는 기능 : findById();

3) DB 에서 회원 이름을 찾는 기능 : findByName();

4) DB 에서 저장된 모든 데이터 조회 : findAll();

public interface MemberRepository {
    Member save(Member member); // save : 회원이 저장
    Optional<Member> findById(Long id); // 저장소에서 회원 아이디 찾기
    Optional<Member> findByName(String name); // 저장소에서 회원이름 찾기
    List<Member> findAll(); // 저장소에서 회원 리스트 전체 반환
}

* Optional<> : nullPointException 을 처리하기 위해 findById 와 findByName 을 Optional 이라는 클래스로 감싸서 정의 하였다.

 

사용 예) 

Optional.ofNullable(store.get(id));

@Override
// 저장된 id를 꺼내오는 찾는 기능 (꺼냄)
public Optional<Member> findById(Long id) {
    return Optional.ofNullable(store.get(id)); // id를 꺼낼 때 NPE 를 방지하기 위해 Optional.ofNullable 로 get(id) 를 감싸준다.
}

 

 

 

4-2. 저장소(Repository) - Interface 에서 정의한 기능을 구현할 class 설계

@Repository
public class MemoryMemberRepository implements MemberRepository{

    private static Map<Long, Member> store = new HashMap<>();
    private static long sequence = 0L; // key 값을 생성해주는 변수

    @Override
    // id를 setting 을 하고 store 에 저장 해주는 기능
    public Member save(Member member) {
        member.setId(++sequence);
        store.put(member.getId(), member);
        return member;
    }

    @Override
    // 저장된 id를 찾는 기능 (꺼냄)
    public Optional<Member> findById(Long id) {
        return Optional.ofNullable(store.get(id)); // id를 꺼낼 때 NPE 를 방지하기 위해 Optional.ofNullable 로 get(id) 를 감싸준다.
    }

    @Override
    // 저장된 name 을 꺼내오는 기능
    public Optional<Member> findByName(String name) {
        return store.values().stream()
                .filter(member -> member.getName().equals(name))
                .findAny();
    }

    @Override
    public List<Member> findAll() {
        return new ArrayList<>(store.values());
    }

    public void clearStore() {
        store.clear();
    }
}

 

 

5. 회원 서비스 클래스 설계 (실제 비즈니스 로직 작성) - 회원 가입, 조회, 이벤트 발생 로직 처리

(중복 가입 시 별도의 메세지 출력 등)

import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
import org.springframework.stereotype.Service;

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

@Service
public class MemberService {

    private final MemberRepository memberRepository;

    // Dependency Injection (의존성 주입) ??..
    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    /**
     * 회원 가입 로직
     */
    public Long join(Member member) {
        // 같은 이름이 있는 중복 회원 불가
        validateDuplicateMember(member); // 하위 메서드로부터 정의된 중복회원 검증 기능을 join 시 호출 하여 수행
        memberRepository.save(member);
        return member.getId();
    }

    // 중복회원 검증 기능을 별로의 메서드(validateDuplicateMember)로 구현
    private void validateDuplicateMember(Member member) {
        memberRepository.findByName(member.getName())
                .ifPresent(m -> {
                    throw new IllegalStateException("이미 존재하는 회원입니다.");
                });
    }

    /**
     * 전체 회원 조회 로직
     */
    public List<Member> findMembers() {
        return memberRepository.findAll();
    }

    // id를 조회 했을 때
    public Optional<Member> findOne(Long memberId) {
        return memberRepository.findById(memberId);
    }
}

 

'Spring > Framwork' 카테고리의 다른 글

DI (Dependency Injection)  (1) 2024.05.01
2. Web 기초 설계 - Controller 설계와 Spring Bean & 의존 관계  (0) 2024.04.30
BeanFactory & ApplicationContext 간단 설명  (0) 2024.03.28
IoC 란?  (0) 2024.03.28
DI 컨테이너 란?  (0) 2024.03.26