본문 바로가기
📝 회고/🤝 코드스쿼드 백엔드 프로젝트

[프로젝트 회고] : Java WAS 개발

by kukim 2022. 6. 12.
  Java WAS (전체 소스코드)
배운 것 WAS, Socket, Unit Test, framework 
기간 22.03.21 ~ 22.04.01 (10일) 
팀원 @쿠킴, @테리
Step 1 HTTP Get 응답/ 1단계 PR
Step 2 GET으로 회원가입 기능 구현 / 2단계 PR
Step 3 POST로 회원 가입 / 3단계 PR
Step 4 쿠키를 이용한 로그인 구현/ 4단계 PR
Reviewer @Honux, @Dion

 


Java Was 프로젝트는 이전 스프링 카페 프로젝트와 동일한 웹사이트 구조로 스프링 프레임워크 없이 자바, 소켓 프로그래밍을 활용해 간단한 WAS를 구현한다. 박재성님의 책 "자바 웹 프로그래밍 Next Step"의 ch 2,3,4 와 주제와 유사하다. 스프링을 사용하며 당연하게 사용하는 톰캣, 서블릿이 얼마나 간편한지 알게되었고 프레임워크의 추상화 레벨이 상당히 높고, 이를 제대로 사용하려면 내부 동작 방식을 잘 알아야겠구나 생각했다.

 

- 프로젝트 주차 회고

2022.03.27 - [📝 회고/🗓 일일, 주간 회고] - [주간 회고] 22.03. 4주차 - "DIY : WAS 개발해보기"

2022.04.10 - [📝 회고/🗓 일일, 주간 회고] - [주간 회고] 22.03. 5주차 - "DIY : WAS 개발 2 & AWS 공부"

 


프로젝트하며 배운 

협업

함께 코딩해본 적 없는 팀원과 함께하기 위해 그라운드 룰 정했다. 특별한 점은 짧은 프로젝트 기간, 프레임워크 없이 직접 프레임워크 구조를 잡고 가야 한다고 생각하여 모든 과정을 페어 프로그래밍을 도입했다. 그 전에도 페어프로그래밍을 시도했었지만 항상 만족스럽진 못했다. 이번엔 페어 프로그래밍의 안티 패턴들 글을 참고하여 연습하였다.

개선점

'비생산적인 산만함을 허용한 문제.' 

예를 들어 팀원간에 코딩 스타일이 다르니 서로에게 팁이나 새로운 기술을 배우곤 한다. 한 명이 타인에게 배운 내용을 잊지 않기 위해 코딩을 잠시 멈추고 기록하였다. 이때 상대방은 아무것도 하지 않고 기다리게 된다. 상대방을 가만히 있게 만들면 안 된다. 

 

 '역할을 정해진 시간 외에 바꾼 것'

드라이버와 네비게이터는 서로 다른 뇌를 쓴다. 한 명은 코딩에만 집중하고, 한 명은 설계에만 집중하게 된다.

역할을 나눈 장점은 컨텍스트 스위칭을 하지 않고 한 가지 일에만 집중할 수 있다. 또한 한 가지 일에만 집중하면 효율이 떨어질 수 있기 때문에 역할을 바꿔 리프레쉬한다. 문제는 드라이버(코딩)와 내비게이터(설계) 능력이 익숙하지 못했다. 내비게이터가 설계를 말했고 드라이버가 운전을 익숙하게 하지 못하고 역으로 내비게이터에게 운전대를 맡긴 경우가 있었다. 균형 있는 시간을 갖지 못했다.

개선점

네비게이터 입장에서 드라이버가 이해할 수 있는 가장 높은 추상화로 설명하자, 드라이버가 이해하지 못했다면 좀 더 자세하게 다시 설명하자. 드라이버는 반대로 너무 빨리 드라이빙하지 말자 내비게이터의 추상화에 혼자 구현하지 말고 내비게이터가 잘 따라오는지 소통하자

 

 

반복 코드 추상화(FrontController)

HTTP Requset 요청에 따라 URI 마다 다른 기능을 작동해야 한다.

처음에는 아래 예처럼 if 조건문으로 기능을 실행했다.  

	public void run() {
		log.debug("New Client Connect! Connected IP : {}, Port : {}", connection.getInetAddress(),
			connection.getPort());

		try (InputStream in = connection.getInputStream();
			OutputStream out = connection.getOutputStream()) {
			Request request = createRequest(in);

			byte[] body = null;
			if ("/user/create".equals(request.getUri())) { // 조건문으로 기능 구분
				User user = new User(request.getParam("userId"),
					request.getParam("password"),
					request.getParam("name"),
					request.getParam("email"));
				log.debug("회원가입완료 {}",user );
				body = Files.readAllBytes(new File("./webapp/" + "index.html").toPath());
			} else {
				body = Files.readAllBytes(new File("./webapp/" + request.getUri()).toPath());
			}

			DataOutputStream dos = new DataOutputStream(out);
			response200Header(dos, body.length);
			responseBody(dos, body);

		} catch (IOException e) {
			log.error(e.getMessage());
		}
	}

위 코드도 동작하지만, API가 많아질수록 매번 if 문으로 작성하기엔 가독성과 코드양이 증가했다.

김영한님의 스프링 MVC 강의를 듣으며 FrontController 구조를 알게 되었고 프로젝트에도 적용시킬 수 있었다.

		try (InputStream in = connection.getInputStream();
			OutputStream out = connection.getOutputStream();
			BufferedReader bufferedReader = new BufferedReader(
				new InputStreamReader(in, StandardCharsets.UTF_8));
			DataOutputStream dataOutputStream = new DataOutputStream(out)) {

			Request request = createRequest(bufferedReader);
			Response response = new Response();

			frontController.service(request, response); // 프론트 컨트롤러 사용

			sendResponse(dataOutputStream, response);
		} catch (IOException e) {
			log.error(e.getMessage());
		}

동시성 문제

프로젝트에서 사용하는 DB는 메모리 기반, 정적으로 Map 자료구조를 단순하게 사용하고 있었다. 

모든 스레드에서 Map 자료구조에 접근할 수 있기 때문에 동시성 문제가 발생할 수 있기 때문에 ConcurrentHashMap()을 사용하였다.

public class DataBase {
    
    // 단순 HaspMap
    private static Map<String, User> users = Maps.newHashMap();
 	
    // ConcurrentHashMap 
    private static Map<String, User> users = new ConcurrentHashMap();

}

 

 

싱글톤 사용

모든 클라이언트가 공통으로 사용하는 컨트롤러는 매번 객체를 생성할 필요가 없기 때문에 싱글톤을 사용하였다. 단, 싱글톤 사용할 때 멤버 변수는 공유되기 때문에 사용을 자제해야 한다.

 

 

MVC 계층 구조

현재 프로젝트에선 사용자의 요청을 프론트 컨트롤러가 해당 컨트롤러의 process 메서드를 실행하여 로직을 실행한다. process 메서드에 모든 로직이 들어있기 때문에 가독성과 유지보수에 어려움이 있다. 왜 스프링 MVC에서 컨트롤러/서비스/리포지토리 계층을 구분 짓는지 조금은 더 피부로 와닿게 되었다.

앞으로

스프링 프레임워크를 직접 구현해볼 수 있어 좋은 경험이었다. 짧은 시간 동안 스프링의 모든 것을 알 수 없어 아쉬움이 남았다. 어노테이션을 활용하여 계층을 구분하거나 DI를 직접 구현하지 못했다. 코드 스쿼드 과정이 끝나고 사이드 프로젝트로라도 박재성님의 Next Step 책을 완독 해야겠다.

 

+a) 코드스쿼드 과정이 끝나고 22.08 Next Step 스터디를 시작했다.!

 

댓글