첫번째 프로젝트

DDRRDDDD·2023년 8월 30일
0

첫번째 프로젝트

목록 보기
1/1
post-thumbnail

첫 프로젝트에 대한 포스팅입니다.
프로젝트가 끝나고 시간이 많이 지나서 포스팅이 엉성할 수 있습니다.
제가 맡은 부분에 관해서 기술합니다.


개요

식품 도매 사이트

식품 도매 사이트라고 쓰고 온라인 쇼핑몰 사이트라고 읽으면 될 거 같다
기억은 잘 나지 않지만 쇼핑몰 사이트를 돌아다니며 참고하여 만들었다

그중에 내가 맡은 일은 물품 및 카테고리별 검색 개발, Service 구조 설계, 전체적인 페이지의 레이아웃 설계,
마지막으로 버그는 거의 내가 잡았던 기억이 있다.

  • 사용 기술 : Java, Servlet/JSP, MySQL
  • 개발 기간 : 7일

https://github.com/DDRRDDDD/ERP_System


ERD


물품 및 카테고리별 검색

1. 시퀀스 다이어그램

2. 코드

카테고리 검색, 물품 검색 후 같은 물품 리스트 페이지를 띄우기 때문에 아래와 같이 코드를 구성해보았다

	public class ProductAction implements Action{
	
	private String keyword;
	private String code;
	
	@Override
	public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		this.keyword = request.getParameter("keyword");
		this.code = request.getParameter("code");
		
        // 잘못된 요청에 대한 유효성 검사
		if(this.code != null || !this.keyword.equals("")) {	
			request.setAttribute("list",getSearchProduct());
			request.setAttribute("result", getSearchResult());
		}
		
		request.getRequestDispatcher("/").forward(request, response);
	}
    
    // 키워드가 null인지 확인하여 키워드 검색인지 카테고리 검색인지 판단
    private List<Product> getSearchProduct() {
		return this.keyword != null ?
				getProductListByKeyword() : getProductListByCategory();
	}
	
	// 키워드가 포함되어있는 리스트를 반환
	private List<Product> getProductListByKeyword() {
		ProductDAO productDao = ProductDAO.getInstance();
		List<Product> productList = productDao.getProductList();
		
		return productList.stream()
						  .filter(product -> product.getName().contains(this.keyword))
						  .collect(Collectors.toList());
	}
	
	// 카테고리 리스트를 반환
	private List<Product> getProductListByCategory(){
		int categoryId = Integer.parseInt(this.code);
		ProductDAO dao = ProductDAO.getInstance();
		return dao.getProductsByCategory(categoryId);
	}
	
	// 키워드가 null인지 확인하여 검색 결과를 반환
	private String getSearchResult() {
		return this.keyword != null ? 
				"'"+this.keyword+"'에 대한 검색 결과" : getCategoryByCode();		   
	}
	
	// 카테고리 이름을 반환
	private String getCategoryByCode() {
		int tagetCode = Integer.parseInt(this.code);
		ProductCategoryDAO categoryDao = ProductCategoryDAO.getInstance();
		return categoryDao.getCategroyNameById(tagetCode);
	}

}

Service 구조 설계

1. 클래스 다이어그램


(Action Interface를 상속받는 일부 클래스만 가져왔습니다.)

  • Service
    Servlet 클래스로 클라이언트 요청을 Action의 excute메서드로 응답합니다.
  • ActionFactory
    Action의 구현체를 반환합니다.
  • ActionType
    Enum 클래스, Action에 대한 객체와 처리할 요청의 command를 가지고 있습니다.
  • Action
    요청에 대한 처리를 추상화한 인터페이스입니다.
  • ActionImpl(LoginAction 등)
    Action인터페이스의 구현체입니다.

2. 설명

팀원들의 주된 오류의 원인 중 하나는 web.xml 설정 실수였다 제대로 구현하더라도 매핑에서의 실수가 빈번하였고, 추가로 이클립스 자체 이슈인 듯한 xml 작성/수정이 너무 느리고 수정사항 반영이 안 되는 경우도 있었다

위 구조를 설계하여 servlet 매핑은 Service 클래스 하나로만 하게 하여 web.xml의 애로사항을 극복하였고, 또한 팀원들은 Action 인터페이스의 구현체로 비즈니스 로직에 집중할 수 있도록 하여 프로젝트 수행 피로도를 줄였다


전체적인 페이지의 레이아웃 설계

1. 페이지 구성

2. 코드

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="../resources/main.css">
<jsp:useBean id="main" class="model.MainVariables" scope="application"/>
<c:set var="main" value="${applicationScope.main}"/>
</head>
<c:import url="header" />
<body>
	<div class="container">
		<div class="category-list">
			<c:import url="category" />
			<img id="category-img" src="../resources/images/salesBanner.jpg">
		</div>
      	<!-- 컨텐츠가 변화할 화면 -->
		<div class="main-banner">
			<c:choose>
				<c:when test="${not empty param.content }">
					<c:import url="${param.content }" />
				</c:when>
				<c:when test="${not empty requestScope.content }">
					<c:import url="${requestScope.content }" />
				</c:when>
				<c:otherwise>
					<img id="event-banner" src="../resources/images/event-banner.jpg">
				</c:otherwise>
			</c:choose>
		</div>
      	<!-- 컨텐츠가 변화할 화면 -->
	</div>
	<script src="../resources/validation.js"></script>
</body>
<c:import url="footer" />
</html>

(header, footer, category는 생략)

3. 설명

JSTL를 사용하여 화면을 구성하였고, .main-banner가 본문이다

c:choose태그를 사용하여 GET, POST, 나머지 분기문을 작성하여, 해당 content에 맞는 URL 화면을 본문에 띄우게 된다

추가로

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<jsp-config>
		<jsp-property-group>
			<url-pattern>*.jsp</url-pattern>
			<include-prelude>/WEB-INF/taglibs.jsp</include-prelude>
		</jsp-property-group>
	</jsp-config>

JSP 파일 만들 때 종종 깜빡하고 prefix선언을 하지 않는 경우도 주된 오류의 원인이였어서
중복을 제거하여 위 코드와 더불어 팀원들이 JSP파일을 만들 때 메인 컨텐츠에 온전히 집중할 수 있게 하였다.


💡 뒤늦은 회고

생에 첫 프로젝트를 이렇게 마무리했다 그만큼 생각을 많이 하고 짧은 시간 안에 온전히 프로젝트를 수행할 수 있게 고민을 정말 많이 했기도 하다. 어찌 보면 빠르게 프로젝트를 진행하기 위해 고안한 방법들이지만 이게 우리 팀에게는 독으로 다가왔었다.

학원에서 가르쳐주지 않은 방법으로 프로젝트를 시도하였고, 이 방법이 가령 생산성을 높이는 방법일지 몰라도
나의 방법이기에 팀원들에게 혼란을 야기한 거 같다 더 나아가 현재 팀이 처한 환경과 자원의 한계를 알고 그것에 맞게 팀원과 함께 상황에 맞게 유연하게 대처하는 방법도 어느 정도 필요한 거 같다는 생각이 든다.

팀 프로젝트는 절대 자아실현의 공간이 아닌 만큼 내가 실행하고자 하는 방법론이나 계획이 있으면 충분한 설명과 납득할만한 계획 그리고 그만한 시간이 어느 정도 충분히 필요하다는 사실을 알았다. 또한 자기 자신이 무엇을 해야 하는지 정확히 인지하고 진행 상황이나 맞춰가야 할 부분에 대해서 충분한 소통을 해야 한다고 느꼈다

프로그래머는 단순 코드를 잘 짜는데 그치지 않고, 여러 가지 부가적인 능력이 정말 중요하다는 깨달음을 얻었다

첫술에 배부를 수 없는 법이다 좀 더 나은 프로그래머가 되기 위해 좀 더 생각하고 고민하며 공부해야겠다는 마음가짐으로 더욱 나아가는 수밖에 없다고 생각한다

profile
코드 뇌피셜 블로그

0개의 댓글