📌 오늘 학습한 주제
- MVC 계층형 아키텍처 (Controller - Service - DAO/Repository) 구조 설계
- 의존성 주입(Dependency Injection, DI)과 팩토리 패턴(
BlogBeanFactory) 결합
- 인터페이스(
BlogReactService) 기반 비즈니스 로직 규격화 및 구현체(BlogReactServiceImpl) 분리
Map<String, Object>을 활용한 엔드포인트 URL 라우팅 및 싱글톤(Singleton) Bean 관리
💡 오늘 배운 것 — 나만의 언어로
① 오늘의 목표
- 자바 백엔드 아키텍처의 핵심인 Controller, Service, DAO 계층을 분리하고, BeanFactory를 통해 의존성을 주입(DI)하여 싱글톤 기반의 객체 라이프사이클을 관리하는 흐름 완성하기
② 학습할 내용
- 계층별 역할 분리 (Layered Architecture): 데이터 접근 전담 계층인
BlogReactDao, 비즈니스 로직을 처리하는 BlogReactService, 클라이언트 요청을 매핑하는 Controller 구조로 역할을 명확히 분리했다.
- 의존성 주입 (Dependency Injection):
BlogReactServiceImpl에 BlogReactDao를 생성자 주입 방식으로 전달하고, ListController에 BlogReactService를 주입하여 객체 간 결합도를 낮췄다.
- BeanFactory & 싱글톤 라우팅 (
BlogBeanFactory.java): getInstance()로 단일 팩토리 인스턴스를 유지하고, Map 자료구조에 요청 경로("list.inspire")와 해당 컨트롤러 인스턴스를 매핑하여 Front Controller 패턴의 기반을 마련했다.
💻 오늘 핵심 코드
1. BeanFactory를 통한 의존성 주입 및 엔드포인트 바인딩 (BlogBeanFactory.java)
package features.blogs.factory;
import java.util.HashMap;
import java.util.Map;
import features.blogs.controller.ListController;
import features.blogs.repository.BlogReactDao;
import features.blogs.service.BlogReactService;
import features.blogs.service.BlogReactServiceImpl;
public class BlogBeanFactory {
private Map<String, Object> map;
private static BlogBeanFactory instance;
private BlogReactService service;
private BlogReactDao dao;
private BlogBeanFactory() {
map = new HashMap<>();
dao = new BlogReactDao();
service = new BlogReactServiceImpl(dao);
map.put("list.inspire", new ListController(service));
}
public static BlogBeanFactory getInstance() {
if (instance == null) {
instance = new BlogBeanFactory();
}
return instance;
}
public Object getBean(String endPoint) {
return map.get(endPoint);
}
}
2. Service 인터페이스 및 구현체 분리 (BlogReactService.java & BlogReactServiceImpl.java)
package features.blogs.service;
import java.util.List;
import features.blogs.domain.dto.BlogResponseDTO;
import features.blogs.repository.BlogReactDao;
public class BlogReactServiceImpl implements BlogReactService {
private BlogReactDao dao;
public BlogReactServiceImpl(BlogReactDao dao) {
this.dao = dao;
}
@Override
public List<BlogResponseDTO> list() {
System.out.println("debug >>>> blog service list ");
return dao.findByAll();
}
}
3. DAO 더미 데이터 초기화 및 조회 (BlogReactDao.java)
package features.blogs.repository;
import java.util.ArrayList;
import java.util.List;
import features.blogs.domain.dto.BlogResponseDTO;
public class BlogReactDao {
private List<BlogResponseDTO> blogs;
public BlogReactDao() {
blogs = new ArrayList<>(List.of(
BlogResponseDTO.builder().blogId(1).title("react").content("state").email("lim").viewCnt(10).build(),
BlogResponseDTO.builder().blogId(2).title("java").content("oop").email("kim").viewCnt(20).build(),
BlogResponseDTO.builder().blogId(3).title("spring").content("mybatis").email("lee").viewCnt(30).build()
));
}
public List<BlogResponseDTO> findByAll() {
return blogs;
}
}
🛠️ 실습 / 결과물 & 참고 자료
③ 실습 / 결과물
- 강의 실습코드:
BlogBeanFactory.java, BlogReactDao.java, BlogReactService.java, BlogReactServiceImpl.java 연동을 통해 엔드포인트(list.inspire) 요청 시 Controller -> Service -> DAO 계층을 거쳐 전체 블로그 목록 데이터를 반환하는 아키텍처 완성.
④ 참고 자료
- Oracle Java Documentation: Java Collections Framework (
Map, List)
- Software Design Patterns: Front Controller Pattern & Dependency Injection
🔍 문제와 해결
- 막힌 부분: 클라이언트가 비즈니스 로직과 데이터베이스에 직접 접근할 때 발생하는 코드 결합도 및 유지보수성 저하 문제 점검.
- 해결 방법: 인터페이스(
BlogReactService)로 표준 명세를 정의하고, 생성자를 통한 의존성 주입(DI)과 팩토리 패턴(BlogBeanFactory)을 도입해 각 계층의 책임을 독립적으로 분리함.
🎯 다음에 할 일