TIL

조지성·2022년 4월 4일
0

TIL

목록 보기
52/78
post-thumbnail

스프링 DI

의존이란?

  • DI는 의존 주입이다.
  • 의존 : 객체 간의 의존을 의미
    • MemberRegisterService에서 MemberDao 클래스의 메서드를 사용
    • 한 클래스가 다른 클래스의 메서드를 실행할 때 이를 의존한다라고 표현
    • 의존은 변경에 의해 영향을 받는 관계를 의미
    • 의존하는 대상을 구하는 방법은 의존 대상 객체를 직접 생성하는것
    • private MemberDao memberDao = new MemberDao();
  • 클래스 내부에서 직접 의존 객체를 생성하는 것이 쉽긴 하지만 유지보수 관점에서 좋지 않음 따라서 DI를 이용해서 의존 객체를 구함
package chap02;

public class MemberRegisterService {
		private MemberDao memberDao = new MemberDao();
		
		public void regist(RegisterRequest req) {
			//이메일로 회원 데이터 조회
			Member member = memberDao.selectByEmail(req.getEmail());
			
			if(member != null) {
				//같은 이메일을 가진 회원이 존재하면
				throw new DuplicateMemberException("에러");
			}
			//같은 이메일을 가진 회원 없으면
			Member newMember = new Member();
			memberDao.insert();
		}
}

DI를 통한 의존 처리

  • DI는 의존하는 객체를 직접 생성하는 대신 의존 객체를 전달받는 방식을 사용
  • DI를 사용하면 변경의 유연함이 생긴다.
package spring;

public class MemberRegisterService {
		
		public MemberDao memberDao;
		
		
		// 의존 객체를 전달 받아서 주입
		// 생성자를 통해 의존하고있는 객체를 주입 받은 것
		public MemberRegisterService(MemberDao memberDao) {
			this.memberDao = memberDao;
		}
		
		public void regist(RegisterRequest req) {
			//이메일로 회원 데이터 조회
			Member member = memberDao.selectByEmail(req.getEmail());
			
			if(member != null) {
				//같은 이메일을 가진 회원이 존재하면
				throw new DuplicateMemberException("에러");
			}
			//같은 이메일을 가진 회원 없으면
			Member newMember = new Member();
			memberDao.insert();
		}
}

예제 프로젝트

회원 데이터 관련 클래스

package com.jisung.spring;

import java.time.LocalDateTime;

public class Member {
	
	private Long id;
	private String email;
	private String password;
	private String name;
	private LocalDateTime registerDateTime;
	
	public Member(String email, String password, String name, LocalDateTime registerDateTime) {
		this.email = email;
		this.password = password;
		this.name = name;
		this.registerDateTime = registerDateTime;
	}

	public Long getId() {
		return id;
	}

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

	public String getEmail() {
		return email;
	}

	public String getPassword() {
		return password;
	}

	public String getName() {
		return name;
	}

	public LocalDateTime getRegisterDateTime() {
		return registerDateTime;
	}
	
	//회원 비밀번호 변경
	public void changePassword(String oldPassword, String newPassword) {
		if(!password.equals(oldPassword)) {
			throw new WrongIdPasswordException();
		}
		this.password = newPassword;
	}
}
package com.jisung.spring;

//이전비밀번호와 현재비밀번호비교해서 오류발생
public class WrongIdPasswordException extends RuntimeException{
	
}
package com.jisung.spring;

import java.util.HashMap;
import java.util.Map;

//회원 정보 저장
public class MemberDao {
	private static long nextId = 0;
	
	private Map<String, Member> map = new HashMap<String, Member>();
	
	public Member selectByEmail(String email) {
		return map.get(email);
	}
	
	public void insert(Member member) {
		member.setId(++nextId);
		map.put(member.getEmail(),member);
	}
	
	public void update(Member member) {
		map.put(member.getEmail(), member);
	}
}

회원 가입 처리 관련 클래스

package com.jisung.spring;

//동일 이메일을 갖고 있는 회원이 존재하면 예외발생
public class DuplicateMemberException extends RuntimeException{
	public DuplicateMemberException(String message) {
		super(message);
	}
}
package com.jisung.spring;

//회원가입을 처리할 때 필요한 이메일,암호,이름 데이터를 담고있는 클래스
public class RegisterRequest {
	private String email;
	private String password;
	private String confirmPassword;
	private String name;
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getConfirmPassword() {
		return confirmPassword;
	}
	public void setConfirmPassword(String confirmPassword) {
		this.confirmPassword = confirmPassword;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	//비밀번호와 비밀번호 확인이 같은지
	public boolean isPasswordEqualToConfirmPassword() {
		return password.equals(confirmPassword);
	}
}
package com.jisung.spring;

import java.time.LocalDateTime;

//회원등록 클래스
public class MemberRegisterService {
	public MemberDao memberDao;
	
	
	// 의존 객체를 전달 받아서 주입
	// 생성자를 통해 의존하고있는 객체를 주입 받은 것
	public MemberRegisterService(MemberDao memberDao) {
		this.memberDao = memberDao;
	}
	
	public Long regist(RegisterRequest req) {
		//이메일로 회원 데이터 조회
		Member member = memberDao.selectByEmail(req.getEmail());
		
		if(member != null) {
			//같은 이메일을 가진 회원이 존재하면
			throw new DuplicateMemberException("dup email "+ req.getEmail());
		}
		//같은 이메일을 가진 회원 없으면
		Member newMember = new Member(req.getEmail(), req.getPassword(), req.getName(), LocalDateTime.now());
		memberDao.insert(newMember);
		return newMember.getId();
	}
}

암호변경 관련 클래스

package com.jisung.spring;

//비밀번호 변경 클래스
public class ChangePasswordService {
	private MemberDao memberDao;
	
	public void changePassword(String email,String oldPwd, String newPwd) {
		Member member = memberDao.selectByEmail(email); // 이메일을 통해 회원 정보 가져옴
		
		//중복된 회원이 있으면
		if(member == null) {
			throw new MemberNotFoundException();
		}
		//비밀번호 변경
		member.changePassword(oldPwd, newPwd);
		//회원정보 업데이트
		memberDao.update(member);
	}

	//의존객체 주입
	public void setMemberDao(MemberDao memberDao) {
		this.memberDao = memberDao;
	}
	
	
}
package com.jisung.spring;

//이메일에 해당하는 member가 존재하지 않을 때
public class MemberNotFoundException extends RuntimeException {

}

객체 조립기

  • 메인 메서드에서 객체를 주입하는것도 괜찮은 방법
  • 메인 메서드에서 객체를 주입하지 않고 객체를 주입해주는 클래스를 따로 작성
    • 조립기 클래스
package assembler;

import com.jisung.spring.ChangePasswordService;
import com.jisung.spring.MemberDao;
import com.jisung.spring.MemberRegisterService;

public class Assembler {
	private MemberDao memberDao;
	private MemberRegisterService regSvc;
	private ChangePasswordService pwdSvc;
	
	public Assembler() {
		memberDao = new MemberDao();
		regSvc = new MemberRegisterService(memberDao);
		pwdSvc = new ChangePasswordService();
		pwdSvc.setMemberDao(memberDao);
	}

	public MemberDao getMemberDao() {
		return memberDao;
	}

	public MemberRegisterService getRegSvc() {
		return regSvc;
	}

	public ChangePasswordService getPwdSvc() {
		return pwdSvc;
	}
	
	
}

조립기 사용예제

package main;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import com.jisung.spring.ChangePasswordService;
import com.jisung.spring.DuplicateMemberException;
import com.jisung.spring.MemberNotFoundException;
import com.jisung.spring.MemberRegisterService;
import com.jisung.spring.RegisterRequest;
import com.jisung.spring.WrongIdPasswordException;

import assembler.Assembler;

public class MainForAssembler {
	
	private static Assembler assembler = new Assembler();
	
	public static void main(String[] args) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		while(true) {
			System.out.println("명령어를 입력하세요 ");
			String command = reader.readLine(); // 한줄입력
			//exit입력받으면 종료
			if(command.equalsIgnoreCase("exit")) {
				System.out.println("종료합니다.");
				break;
			}
			//new로 시작하면 
			if(command.startsWith("new ")) {
				processNewCommand(command.split(" "));
				continue;
			}
			//change로 시작하면..
			if(command.startsWith("change ")) {
				processChangeCommand(command.split(" "));
				continue;
			}
			printHelp();
		}
	}
	
	private static void processNewCommand(String[] arg) {
		if(arg.length != 5) {
			printHelp();
			return;
		}
		MemberRegisterService regSvc = assembler.getRegSvc();
		RegisterRequest req = new RegisterRequest();
		req.setEmail(arg[1]);
		req.setName(arg[2]);
		req.setPassword(arg[3]);
		req.setConfirmPassword(arg[4]);
		
		if(!req.isPasswordEqualToConfirmPassword()) {
			System.out.println("일치하지 않음");
			return;
		}
		
		try {
			regSvc.regist(req);
			System.out.println("등록했습니다.");
			
		} catch (DuplicateMemberException e) {
			System.out.println("이미 존재하는 이메일 입니다.");
		}
	}
	
	private static void processChangeCommand(String[] arg) {
		if(arg.length != 4) {
			printHelp();
			return;
		}
		ChangePasswordService changePwdSvc = assembler.getPwdSvc();
		
		
		try {
			 changePwdSvc.changePassword(arg[1], arg[2], arg[3]);
			 System.out.println("암호 변경완료");
			
		} catch (MemberNotFoundException e) {
			System.out.println("존재하지 않은 이메일입니다.");
		} catch (WrongIdPasswordException e) {
			System.out.println("이메일과 암호가 일치하지 않습니다.");
		}
	}
	
	private static void printHelp() {
		System.out.println("잘못된 명령입니다!");
	}
}
profile
초보 개발자의 성장기💻

0개의 댓글