😊Separation of Concerns
책임과 역할 분리는 소프트웨어 설계 원칙에서 매우 중요한 개념임
시스템의 각 구성 요소가 자신만의 책임을 가지도록 설계하고, 역할에 따라 각기 다른 기능을 수행하도록 만드는 것을 의미함
책임(Responsibility) : 각 구성 요소가 처리해야 하는 작업의 범위나 의무 즉, "내가 무엇을 해야 하는 가?"
ex) 데이터 베이스 관리, 비즈니스 로직 처리, 사용자 인터페이스 제공 등...
역할(Role) : 시스템 내에서 구성 요소가 수행하는 구체적인 기능 즉, "내가 시스템 내에서 어떤 역할을 맡고 있는가?"에 대한 답
ex) Controller, Model, View
분리가 중요한 이유 : 단일 책임 원칙 즉, 하나의 구성 요소는 단 하나의 책임만 가져야 함.
😊Web MVC 패턴(Separation of Concerns)
MVC = Model + View + Controller로 역할을 분리해서 처리하는 구조임.
😊Model(책임 : 데이터 및 비즈니스 로직 처리)
애플리케이션의 데이터와 비즈니스 로직을 담당하고 DB와의 상호 작용을 포함하며, 주로 DAO와 함께 사용함
ex) 사용자 정보, 주문 내역 등
역할 : 데이터를 관리/ 비즈니스 로직을 캡슐화/ View에 데이터를 제공
👍데이터 : 애플리케이션에서 사용하는 정보나 자원임.
ex) 도메인 객체 : 애플리케이션의 핵심 데이터를 나타내는 객체임
ex) Value Object : Java 애플리케이션에서 데이터를 표현하는데 사용되는 객체로, 특정 목적의 데이터를 캡슐화하여 이동시키는 역할을 함. "일반적으로 비즈니스 로직과 관련된 값의 불변성과 동일성을 더 강조함"
👍DAO(Data Access Object) : 데이터베이스 와의 상호작용(내 생각에는 실제 DB 접근하는 행동 자체를 객체화 한것)을 캡슐화하는 객체임.
애플리케이션의 비즈니스 로직과 데이터베이스의 의존성을 분리하여, DB 즉, 흔히 CRUD를 처리하는 역할을 수행함.
😂DAO vs DTO
DAO : DB와 직접 상호작용하여 데이터를 관리 하는 것
DTO : 계층 간 데이터를 전달하기 위한 단순한 객체
👍DTO(Data Transfer Object) : 계층 간 데이터 전송을 위한 객체임.
일반적으로 데이터를 단순히 전달하기 위한 목적으로 사용되며, 비즈니스 로직이나 데이터베이스 작업을 포함하지 않음
😊View(책임 : 사용자 인터페이스)
사용자에게 데이터를 표시하는 UI를 담당.
HTML, JSP, Thymeleaf 등의 템플릿 엔진을 사용
Model에서 받은 데이터를 렌더링하여 사용자에게 보여줌
역할 : 사용자 인터페이스를 정의, 데이터를 읽기 전용으로 표시(UI 렌더링)
😊Controller(책임 : 사용자 요청 처리)
사용자의 입력을 처리하고 적절한 모델(Model)과 뷰(View)를 연결
사용자의 요청(Request)을 처리한 뒤 적절한 service를 호출하여 비즈니스 로직을 수행함
View에 필요한 데이터를 준비하여 반환
역할 : 사용자의 요청을 분석하고 처리 / Model과 View 간의 중재자 역할 / 비즈니스 로직 호출 및 응답 반환
😊Layered Architecture(계층형 아키텍처)
소프트웨어 설계에서 가장 널리 사용되는 구조 중 하나로, 애플리케이션을 기능적 계층(Layer)으로 분리하여 설계하는 방식임. 각 계층이 특정 역할과 책임을 가지며 계층 간의 명확한 경계를 설정하여 코드의 유지보수성, 재사용성, 확장성을 높임.
1) Presentation Layer(프레젠테이션 계층)
역할 : 사용자 UI 처리
책임 : 사용자 요청을 처리하고 데이터를 시각적으로 처리(Controller와 View로 구성)
ex) 웹 애플리케이션 : HTML, CSS, JavaScript
2) Business Logic Layer(비즈니스 로직 계층)
역할 : 애플리케이션의 핵심 비즈니스 로직을 처리
책임 : Presentation Layer와 Data Access Layer 사이의 중간 역할 수행
ex) 상품 가격 계산, 주문 처리, 사용자 권한 관리
예시 : Service 클래스 !!!!!!
서비스 클래스의 기능 :
1. 조율(Coordination) : 여러 DAO와 외부 API를 호출하여 복잡한 작업 흐름(워크 플로우)을 처리
2. 계층 간 의존성 분리 : 컨트롤러와 DAO(데이터 접근 계층) 사이에서 중재자 역할 즉, 데이터 접근에 대한 세부사항을 숨기고, 컨트롤러가 비즈니스 로직과 데이터 접근 로직을 직접 다루지 않게 함.
3) Data Access Layer(데이터 접근 계층)
역할 : 데이터베이스 또는 외부 데이터 소스와의 상호작용
책임 : 데이터 CRUD 작업 처리, 데이터 베이스와 독립된 인터페이스 제공
ex) SQL 쿼리 실행, ORM 사용
4) Database Layer(데이터베이스 계층)
역할 : 데이터를 실제로 저장하고 관리
책임 : 데이터를 영구적 저장, 데이터베이스 스키마 정의 및 인덱싱
ex) MYSQL, PostgreSQL, Redis 등..
😊Java Servlet 주요 메소드
@WebServlet
Java 웹 애플리케이션에서 서블릿을 정의하기 위한 어노테이션임. 서블릿 클래스에 URL 매핑을 지정함.
구성 요소
1. name -> 서블릿의 이름을 설정
2. urlPatterns(혹은 value) -> 서블릿에 매핑될 하나 이상의 URL 패턴을 설정함.
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/example")
public class ExampleServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
response.setContentType("text/html");
response.getWriter().println("<h1>Hello, Servlet!</h1>");
}
}
doGet
역할 : HTTP GET 요청을 처리 / 주로 데이터를 가져오거나 클라이언트가 서버에서 정보를 요청할 때 사용
매소드 시그니처
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
RequestDispatcher는 Java Servlet API에서 제공되는 인터페이스로, 서블릿 간의 요청(Request)을 전달하거나 포함하기 위한 기능을 제공함.
RequestDispatcher의 주요 메소드
1. forward()는 현재 요청을 다른 서블릿이나 JSP로 전달함. 즉, 이때 forward()는 중간 경유지 느낌. 이때 클라이언트는 전달된 요청을 처리하는 서블릿이나 JSP를 직접 알 수 없음
예제)
@WebServlet(name = "inputController" , urlPatterns = "/calc/input")
public class InputController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("InputController...doGet...");
RequestDispatcher dispatcher = req.getRequestDispatcher("/WEB-INF/calc/input.jsp");
dispatcher.forward(req,resp);
}
}
doPost
역할 : HTTP POST 요청을 처리/ 주로 데이터를 서버에 전송하거나 서버에서 특정 작업을 수행할 때 사용함
1)req.getParameter(String name) 메소드
HTTP 요청에서 전달된 특정 파라미터 값을 가져오는 데 사용됨. 주로 폼 데이터나 쿼리 문자열에서 데이터를 읽을 때 사용됨
String getParameter(String name)
메소드 시그니처
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
예제
@WebServlet(name = "calcController" , urlPatterns = "/calc/makeResult")
public class CalcController extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String num1 = req.getParameter("num1");
String num2 = req.getParameter("num2");
System.out.printf(" num1: %s", num1);
System.out.printf(" num2: %s", num2);
}
}
2) sendRedirect()
POST 방식의 처리는 다른 웹 페이지를 보도록 브라우저 화면을 이동시키는 것이 좋음.
이때 사용하는 메소드가 HttpServletResponse의 sendRedirect()임
위의 예제에서 코드를 추가하면
@WebServlet(name = "calcController" , urlPatterns = "/calc/makeResult")
public class CalcController extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String num1 = req.getParameter("num1");
String num2 = req.getParameter("num2");
System.out.printf(" num1: %s", num1);
System.out.printf(" num2: %s", num2);
resp.sendRedirect("/index");
}
}
😊PRG 패턴(Post/Redirect/Get pattern)
웹 애플리케이션 개발에서 중복 데이터 전송 방지와 사용자 경험 개선을 위해 사용되는 설계 패턴임. 주로 폼 제출 후 새로 고침(F5)시 중복 요청 문제를 해결하기 위해 사용됨 또한 사용자 경험 개선을 위해 사용됨(뒤로가기)
PRG 패턴의 기본 개념
1. POST(폼 제출)
사용자가 폼을 제출하면 서버에서 데이터를 처리함 이때 데이터를 저장하거나 업데이트하는 작업이 수행됨
2. Redirect(재요청)
POST 요청 후, 서버는 클라이언트에게 302 Found 응답을 보내고 새로운 URL로 리다이렉트함. 이후 브라우저는 GET 요청을 통해 새로운 URL로 이동함
3. GET(결과 표시)
브라우저는 새로운 URL에 GET 요청을 보내고 서버는 데이터를 읽어와 결과를 사용자에게 표시함
PRG 패턴의 동작 흐름
1. 사용자 폼 제출 → 서버에 POST 요청.
2. 서버에서 데이터를 처리하고, 리다이렉트 응답(302 상태 코드와 함께 새로운 URL 제공).
3. 브라우저가 리다이렉트 URL로 GET 요청을 보냄.
4. 서버는 GET 요청에 따라 결과를 반환.
예제
<form method="POST" action="/submit">
<input type="text" name="username" placeholder="Enter your name">
<button type="submit">Submit</button>
</form>
@WebServlet("/submit")
public class SubmitServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String username = req.getParameter("username");
System.out.println("Username: " + username);
resp.sendRedirect("/result?username=" + username);
}
}
@WebServlet("/result")
public class ResultServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String username = req.getParameter("username");
resp.setContentType("text/html");
resp.getWriter().println("<h1>Welcome, " + username + "!</h1>");
}
}
😒Wireframe
보통 웹 개발시에 여러 페이지를 만들 때 이동이 많기 때문에 설계를 통해 어떤 흐름으로 동작하게 되는지 웹 페이지를 구성하게 되는데 이를 위해 사용되는 것이 Wireframe임
책에선 Mockup / Balsamiq wireframes 등을 소개하였고 나는 Figma를 사용해 보았으니 Figma를 사용해서 포폴 만들어 보자잇