2023. 2. 8. 20:05ㆍIT/ServerSide
요구사항
회원 : 회원 가입/조회, 등급 일반/VIP, 데이터 저장소 미확정(자체 DB/외부 시스템)
할인: 등급에 따라 할인 적용, VIP 1000원 고정 금액 할인, 할인 정책 미확정 (최악의 경우 적용 없음)
주문: 회원 상품 주문,
회원 설계
회원 도메인 협력 관계(기획자) 다이어그램
클라이언트 -> 회원 서비스 (회원가입, 회원조회 등 요구사항 내용) -> 회원 저장소 (객체: 메모리, DB, 외부 시스템 연동)
즉, 요구사항 내용에 대한 다이어그램
회원 클래스 다이어그램 (개발자가 구체화), 정적
<interface>MemberService <--MemberServiceImpl -> <interface> MemberRepository <--MemoryMemberRepository/DbMemberRepository/외부저장소
회원 객체 다이어그램 , 동적
클라이언트(인터페이스) -> 회원 서비스(Impl*) -> 메모리 회원 저장소
*인터페이스의 구현체가 하나일 경우 뒤에 Impl을 붙인다.
-일단 데이터는 메모리 저장소로 진행 (아주 기본적)
중요한 것.
역할과 구현이 잘 나누어져야 좋은 설계다.
전체를 Member/Discount/Order로 나누고,
클라이언트(인터페이스)/서비스(구현체)/저장소(인터페이스)-메모리 저장소(구현체)
각각의 역할과 구현을 잘 분할해야 한다.
강의에서 전체 요구사항과 설계 및 코드까지 다 짜주기 때문에 나는 매우 재미가 없다.
회원 도메인 개발
회원 엔티티 hello.core.member (member package)
- 회원 등급 enum Grade
BASIC, VIP
*enum이 뭘까..
- 회원 엔티티 class Member
private id, name, grade
생성자 Member(id, name, grade)
getter/setter
- 회원 저장소 interface MemberRepository
void save(member)
Member findById(memberId)
- 회원 저장소 구현체(메모리) class MemoryMemberRepository implememts MemberRepoository
private static Map<Long, Member> store = new HashMap<>(); *
//Map, HashMap 따로 공부하자..
//override, implements 빨간 줄, 오류 발생 시 : option + enter
@override
save(member) {
store.put
}
@override
findById(memberId) {
store.get
}
- 회원 서비스 interface MemberService
void join(member)
Member findMember(memberId)
- 회원 서비스 구현체 class MemberServiceImpl
//memberRepository 생성할 때,
MemberRepository memberRepository (인터페이스만 있으면 안된다) = new MemoryMemberRepository()
void join(member) {
memberRepository.save(member)
}
//구현체가 없으면 nullpointer exception
<다형성!>
join이 save를 호출하면 MemoryMemberRepository의 save가 호출되는 것.
실행 및 테스트
- hello.core > MemberApp class
//psvm + enter : public static void main 자동 생성 키맵
MemberService = new MemberServiceImpl
Member member = new Member //멤버 생성, command + option + v : 리팩터링(??)
memberService.join(member) //멤버 저장
Member findMember = memberService.findMember(id)
System.out.println(member.getName()) //생성, 삽입된 멤버
System.out.println(findMember.getName()) //저장된 멤버
여기까지는 순수 자바 코드를 눈으로 검증하는 방법이다.
이렇게 애플리케이션 로직(MemberApp)으로 테스트 하는 것은 좋은 방법이 아니다.
따라서 JUnit Test!
JUnit Test
- test > java > hello.core > member package > class MemberServiceTest
MemberService memberService = new MemberServiceImpl();
@Test //import
void join() {
//given 이런게 주어졌을 때,
Member member = new Member(아이디, 이름, 등급); //멤버 생성
//when 이렇게 하면
memberService.join(member); //멤버 추가
Member findMember = memberService.findMember(아이디); //멤버 찾기
//then 이렇게 된다
Assertions.assertThat(member).isEqualTo(findMember); //생성한 멤버와 찾은 멤버(저장소에서 꺼낸)가 같은지
//Assertions : assertj.core로 선택하기.
오류 내용으로 검증 가능.
Test를 잘 작성하는 게 중요!
회원 도메인 설계의 문제점
OCP, DIP 원칙 위반.
의존 관계가 인터페이스 뿐만 아니라 구현까지 모두 의존 *
*예제 전부 작성 후 문제점과 해결 방안 설명
예를 들면,
//MemberServiceImpl에서,
private final MemberRepository memberRepository = new MemoryMemberRepository();
MemberRepository(Interface 의존), MemoryMemberRepository(실제 할당하는 이 부분의 구현체 의존)
즉 , 추상화/구체화 둘 다 의존하여 DIP 위반
'IT > ServerSide' 카테고리의 다른 글
pip 에러 (0) | 2024.05.18 |
---|---|
ex1 (0) | 2024.05.18 |
[python web project a.k.a pwp] 0.포폴용 커뮤니티 만들기 시작 (0) | 2024.04.30 |
[Spring/스프링 부트 독학 입문] Intellij 설치, 환경 설정, Spring Gradle 프로젝트 생성 (0) | 2023.03.11 |
[스프링부트/김영한 스프링_기본] 1. 인텔리제이 설치/환경 설정/ 편집기 키맵/영어로 (0) | 2023.02.07 |