본문 바로가기
  • Let's study
BackEnd/Java

[Java] 명언 게시판 만들기 - 레이어드 아키텍처 & 리팩토링

by 코딩고수이고파 2026. 7. 22.

레이어드 아키텍처 적용

기존에는 App 클래스가 사용자 입력, 명언 등록, 수정, 삭제, 목록 조회 등 모든 기능을 담당했다.

하지만 기능이 많아질수록 하나의 클래스에 책임이 집중되어 유지보수가 어려워진다.

이를 해결하기 위해 레이어드 아키텍처(Layered Architecture)를 적용하여 역할에 따라 클래스를 분리하였다.

구조 변경

기존 구조

 

App
 ├─ 등록
 ├─ 목록
 ├─ 삭제
 └─ 수정

 

변경 후 구조

 

App
    ↓
WiseSayingController
    ↓
WiseSayingService
    ↓
WiseSayingRepository

 

각 클래스는 자신의 역할만 담당하도록 변경하였다.

App

App은 사용자의 명령을 입력받고, 어떤 기능을 실행할지만 결정한다.

기존처럼 등록, 삭제, 수정 로직을 직접 처리하지 않고 모두 WiseSayingController에게 위임한다.

App은 프로그램의 시작과 명령 분기만 담당하는 클래스가 되었다.

WiseSayingController

Controller는 사용자와의 입출력을 담당한다. 사용자의 요청을 받아 필요한 Service를 호출하고, 결과를 화면에 출력한다.

actionWrite()

  • 명언과 작가를 입력받는다.
  • wiseSayingService.write()를 호출한다.
  • 등록 완료 메시지를 출력한다.

actionList()

  • wiseSayingService.findAllIdDesc()를 호출한다.
  • 조회한 명언 목록을 출력한다.

actionDelete(String cmd)

  • 삭제할 id를 추출한다.
  • wiseSayingService.delete(id)를 호출한다.
  • 삭제 성공 여부를 출력한다.

actoinModify(String cmd)

  • 수정할 명언을 조회한다.
  • 수정 내용을 입력받는다.
  • wiseSayingService.modify()를 호출한다.

WiseSayingService

Service는 프로그램의 핵심 로직을 담당한다. Controller와 Repository 사이에서 필요한 작업을 수행한다.

분리된 메서드

WiseSaying write(String content, String author)

  • 명언 객체를 생성한다.
  • Repository에 저장을 요청한다.

WiseSaying findById(int id)

  • Repository에서 id로 명언을 조회한다.

void modify(WiseSaying w1, String content, String author)

  • 명언과 작가를 수정한다.

boolean delete(int id)

  • Repository에 삭제를 요청한다.

List<WiseSaying> findAllIdDesc()

  • Repository에서 전체 목록을 조회한다.

WiseSayingRepository

Repository는 데이터 저장 및 조회를 담당한다. ArrayList를 직접 관리하며 데이터와 관련된 작업만 수행한다.

분리된 메서드

WiseSaying save(WiseSaying wiseSaying)

  • 명언을 저장한다.
  • id를 생성하고 ArrayList에 추가한다.

WiseSaying findById(int id)

  • id에 해당하는 명언을 조회한다.

boolean delete(int id)

  • id에 해당하는 명언을 삭제한다.

List<WiseSaying> findAllIdDesc()

  • 등록된 명언 목록을 역순으로 반환한다.

int findIndexById(int id)

  • id에 같은 번호를 가진 명언의 인덱스를 찾는다.

참고

git: WiseSayingController & WiseSayingService 도입

git: WiseSayingRepository 도입

리팩토링

AppContext으로 객체 생성 관리

원래는 Controller, Service에서 직접 객체를 생성하고 있었다.

하지만 이 방식은 객체 생성 위치가 여러 곳에 흩어져 있어 관리하기 어려워 AppContext에서 한 번만 관리하도록 변경하였다.

 

public class AppContext {
    public static Scanner sc = new Scanner(System.in);

    public static WiseSayingRepository wiseSayingRepository = new WiseSayingRepository();
    public static WiseSayingService wiseSayingService = new WiseSayingService();
    public static WiseSayingController wiseSayingController = new WiseSayingController();
}

 

각 클래스는 필요한 객체를 AppContext에서 가져와 사용한다.

 

Scanner sc = AppContext.sc;
WiseSayingService wiseSayingService = AppContext.wiseSayingService;

신규 등록과 수정을 save() 하나로 처리

이전에는 등록과 수정을 각각 따로 처리했다.

Repository의 save()를 수정하여 등록과 수정을 모두 담당하도록 변경하였다.

 

public WiseSaying save(WiseSaying wiseSaying){
    if(wiseSaying.isNew()) {
        lastId++;
        wiseSaying.setId(lastId);
        wiseSaying.setCreatedDate(LocalDateTime.now());
        wiseSayings.add(wiseSaying);
    }

    wiseSaying.setModifiedDate(LocalDateTime.now());

    return wiseSaying;
}

 

기존에 Repository에서 id==0 대신 isNew()를 사용하는 이유는 객체가 새로 생성된 객체인지, 이미 저장된 객체인지 판단하는 책임을 객체에게 맡기기 위해서이다.

 

public boolean isNew() {
    return id == 0;
}

생성일, 수정일 추가

명언 객체에 작성 시간과 수정 시간을 추가하였다.

 

private LocalDateTime createdDate;
private LocalDateTime modifiedDate;

 

생성일은 등록 할 때만,

 

wiseSaying.setCreatedDate(LocalDateTime.now());

 

수정일은 수정과 등록에서 저장된다.

 

wiseSaying.setModifiedDate(LocalDateTime.now());

 

참고

git: AppContext 적용

git: 저장/수정 save 통일

git: createdDate, modifiedDate 추가

댓글