회원 가입 프로젝트 #2

정의정·2023년 6월 12일
0

Spring

목록 보기
6/12
post-thumbnail

💡 회원 가입 프로젝트 #2

이어서 회원 가입 프로젝트를 진행한다. 지난 포스트에서 예고했듯 이번 포스트에서는 객체 조립기와 이를 이용하는 메인 메서드를 다룰 것이다.

📌 순서

  1. 객체 조립기란?
  2. 조립기(Assembler) 작성하기
  3. MainForAssembler 클래스 작성하기

🌟 객체 조립기(Assembler)

지금까지 의존 주입(DI)를 적용시켜 코드를 작성했다. 객체 생성에 사용할 클래스를 변경하기 위해 객체를 사용하는 모든 클래스를 변경할 필요 없이 객체를 주입하는 코드 한 곳만 변경하면 되도록 한 것이다.

하지만 아직 실제 객체를 생성하는 코드를 작성하진 않았다. 그렇다면 Main 메서드에서 객체를 생성하면 되는 것일까? 그것도 틀린 방법은 아니지만 더 나은 방법은 의존 대상 객체를 생성하고 의존 객체를 주입해주는 클래스를 따로 작성하는 것이다.

의존 객체를 주입한다는 것은 서로 다른 두 객체를 조립한다고 생각할 수도 있다. 이런 의미에서 이 클래스를 조립기(Assembler)라고 표현한다.


🌟 조립기(Assembler) 작성하기

assembler라는 패키지를 생성하고 그 안에 조립기(Assembler) 클래스를 작성한다.

1. Assembler

Assembler.java✏️

package assembler;

import spring.ChangePasswordService;
import spring.MemberDao;
import 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 getMemberRegisterService() {
		return regSvc;
	}

	public ChangePasswordService getChangePasswordService() {
		return pwdSvc;
	}
}

Assembler() 메서드에서 MemberRegisterService 객체와 ChangePasswordService 객체에 대한 의존을 주입한다.
MemberRegisterService는 생성자를 통해 MemberDao 객체를 주입받고 ChangePasswordService는 setter를 통해 주입받은 것을 확인할 수 있다.

이렇게 생성한 Assembler 클래스를 사용하는 코드에서는 Assembler 객체를 생성한 뒤 getter를 이용해 필요한 객체를 구한다.


🌟 MainForAssembler 클래스 작성하기

명령어를 콘솔에서 입력받고 알맞은 기능을 수행하도록 main 패키지 안에 Main 메서드를 구현해보자. 명령어는 다음과 같다.

📌 명령어

👉🏻 new : 회원 데이터 추가(회원 가입)
👉🏻 change : 회원 데이터 암호 변경
👉🏻 exit : 프로그램 종료

1. MainForAssembler

MainForAssembler.java✏️

먼저 Assembler를 사용하는 메인 클래스를 작성한다.

package main;

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

import assembler.Assembler;
import spring.ChangePasswordService;
import spring.DuplicateMemberException;
import spring.MemberNotFoundException;
import spring.MemberRegisterService;
import spring.RegisterRequest;
import spring.WrongIdPasswordException;

public class MainForAssembler {
	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();
			if (command.equalsIgnoreCase("exit")) {
				System.out.print("종료합니다.");
				break;
			}
			if (command.startsWith("new ")) {
				processNewCommand(command.split(" "));
				continue;
			} else if (command.startsWith("change ")) {
				processChangeCommand(command.split(" "));
				continue;
			}
			printHelp();
		}
	}

	private static Assembler assembler = new Assembler();

	private static void processNewCommand(String[] arg) {
		if (arg.length != 5) {
			printHelp();
			return;
		}
		MemberRegisterService regSvc = assembler.getMemberRegisterService();
		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("암호와 확인이 일치하지 않습니다.\n");
			return;
		}
		try {
			regSvc.regist(req);
			System.out.println("등록했습니다.\n");
		} catch (DuplicateMemberException e) {
			System.out.println("이미 존재하는 이메일입니다.\n");
		}
	}

	private static void processChangeCommand(String[] arg) {
		if (arg.length != 4) {
			printHelp();
			return;
		}
		ChangePasswordService changePwdSvc = assembler.getChangePasswordService();
		try {
			changePwdSvc.changePassword(arg[1], arg[2], arg[3]);
			System.out.println("암호를 변경했습니다.\n");
		} catch (MemberNotFoundException e) {
			System.out.println("존재하지 않는 이메일입니다.\n");
		} catch (WrongIdPasswordException e) {
			System.out.println("이메일과 암호가 일치하지 않습니다.\n");
		}
	}

	private static void printHelp() {
		System.out.println();
		System.out.println("잘못된 명령입니다. 아래 명령어 사용법을 확인하세요.");
		System.out.println("명령어 사용법");
		System.out.println("new 이메일 이름 암호 암호확인");
		System.out.println("change 이메일 현재비번 변경비번");
		System.out.println();
	}
}

자세히 살펴보기✔️

main()

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();
			if (command.equalsIgnoreCase("exit")) {
				System.out.print("종료합니다.");
				break;
			}
			if (command.startsWith("new ")) {
				processNewCommand(command.split(" "));
				continue;
			} else if (command.startsWith("change ")) {
				processChangeCommand(command.split(" "));
				continue;
			}
			printHelp();
		}
	}

콘솔에서 명령어를 입력받기 위해 System.in을 이용해 BufferedReader를 생성한다. BufferedReader.readLine() 메서드로 콘솔에서 한 줄을 입력받는다.

입력한 문자열이 "exit"일 경우 프로그램을 종료한다.
입력한 문자열이 "new "로 시작하면 processNewCommand() 메서드를 실행한다.
입력한 문자열이 "change "로 시작하면 processChangeCommand() 메서드를 실행한다.
명령어를 잘 못 입력한 경우 printHelp() 메서드를 실행한다.

processNewCommand()

	private static Assembler assembler = new Assembler();

	private static void processNewCommand(String[] arg) {
		if (arg.length != 5) {
			printHelp();
			return;
		}
		MemberRegisterService regSvc = assembler.getMemberRegisterService();
		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("암호와 확인이 일치하지 않습니다.\n");
			return;
		}
		try {
			regSvc.regist(req);
			System.out.println("등록했습니다.\n");
		} catch (DuplicateMemberException e) {
			System.out.println("이미 존재하는 이메일입니다.\n");
		}
	}

Assembler 객체를 생성한다.

processNewCommand() 메서드는 새로운 회원 데이터를 생성한다. 암호가 알맞지 않거나, 중복 이메일이 존재하는 경우 예외 처리를 통해 에러 메시지를 콘솔에 출력한다.
정상적으로 실행되면 회원 데이터가 저장된다. MemberDao 객체의 map에 회원 데이터가 추가된다.

processChangeCommand()

	private static void processChangeCommand(String[] arg) {
		if (arg.length != 4) {
			printHelp();
			return;
		}
		ChangePasswordService changePwdSvc = assembler.getChangePasswordService();
		try {
			changePwdSvc.changePassword(arg[1], arg[2], arg[3]);
			System.out.println("암호를 변경했습니다.\n");
		} catch (MemberNotFoundException e) {
			System.out.println("존재하지 않는 이메일입니다.\n");
		} catch (WrongIdPasswordException e) {
			System.out.println("이메일과 암호가 일치하지 않습니다.\n");
		}
	}

processChangeCommand() 메서드는 암호를 변경한다. 이메일에 해당하는 회원 데이터가 없거나, 암호가 알맞지 않다면 예외 처리를 통해 에러 메시지를 콘솔에 출력한다.
정상적으로 실행되면 MemberDao 객체의 map에 저장된 회원 데이터의 암호가 변경된다.

printHelp()

	private static void printHelp() {
		System.out.println();
		System.out.println("잘못된 명령입니다. 아래 명령어 사용법을 확인하세요.");
		System.out.println("명령어 사용법");
		System.out.println("new 이메일 이름 암호 암호확인");
		System.out.println("change 이메일 현재비번 변경비번");
		System.out.println();
	}

printHelp() 메서드는 명령어가 잘 못 입력된 경우 도움말을 출력한다.


🌟 결과

다음과 같이 정상적으로 실행되는 것을 확인할 수 있다.

명령어를 입력하세요: 
abc

잘못된 명령입니다. 아래 명령어 사용법을 확인하세요.
명령어 사용법
new 이메일 이름 암호 암호확인
change 이메일 현재비번 변경비번

명령어를 입력하세요: 
new abc@def.com abc abc123 abc123
등록했습니다.

명령어를 입력하세요: 
change abc@def abc123 abc456
존재하지 않는 이메일입니다.

명령어를 입력하세요: 
change abc@def.com abc111 abc456
이메일과 암호가 일치하지 않습니다.

명령어를 입력하세요: 
change abc@def.com abc123 abc456
암호를 변경했습니다.

명령어를 입력하세요: 
exit
종료합니다.

🎀 줄이며...

이번 포스트는 Assembler의 개념과 사용법에 대한 내용을 담고 있다.

다음 포스트에서는 드디어 spring을 이용한 객체 조립을 다룬다. 스프링 의존 주입에 대한 설정 정보를 작성하고, 이번에 작성한 MainForAssembler를 스프링 컨테이너를 사용하도록 변경할 것이다.

📖 교재 및 출처

  • 초보 웹 개발자를 위한 스프링5 프로그래밍 입문 | 최범균님 저
profile
배움 기록

0개의 댓글