사이먼's 코딩노트
[Java] 게시판 제작(9) 본문
[게시판 제작 ~ing]
- 작성된 모든 코드는 저의 깃허브 리포지터리에서 확인하실 수 있습니다.
- 리포지터리 주소 URL : https://github.com/psm817/full_stack_proj_2024_03
[게시물 관련 기능 Controller로 이전]
- 앞선 23일차에서 Article과 Memeber를 생성하는 부분을 클래스로 따로 두어 분리해줬고, 회원 관련 기능을 Controller를 도입하여 MemberController.java 클래스로 이전하였다.
- 이번에는 게시물 관련 기능을 ArticleController.java 라는 클래스를 생성하여 이전시켜봅시다.
- 여기서 말하는 게시물 관련 기능이란 article list, article write, article detail, article modify, article delete 라는 명령어를 실행했을 때 동작하는 로직들을 의미한다.
package org.example.controller;
import org.example.dto.Article;
import org.example.dto.Member;
import org.example.util.Util;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class ArticleController {
private Scanner sc;
private List<Article> articles;
public ArticleController(Scanner sc, List<Article> articles) {
this.sc = sc;
this.articles = articles;
}
public void doWrite() {
int id = articles.size() + 1;
System.out.printf("제목 : ");
String title = sc.nextLine();
System.out.printf("내용 : ");
String body = sc.nextLine();
String regDate = Util.getNowDateStr();
Article article = new Article(id, regDate, title, body);
articles.add(article);
System.out.printf("%d번 글이 작성되었습니다.\n", id);
}
public void showList(String cmd) {
if(articles.size() == 0) {
System.out.println("게시물이 없습니다.");
return;
}
String searchKeyword = cmd.substring("article list".length()).trim();
// articles와 연결된 forListArticles
List<Article> forListArticles = articles;
if(searchKeyword.length() > 0) {
forListArticles = new ArrayList<>();
for(Article article : articles) {
if(article.title.contains(searchKeyword)) {
forListArticles.add(article);
}
}
}
if (forListArticles.size() == 0) {
System.out.println("검색결과가 존재하지 않습니다.");
return;
}
System.out.println("번호 | 조회수 | 제목");
for(int i = forListArticles.size() - 1; i >= 0; i--) {
Article article = forListArticles.get(i);
System.out.printf("%4d | %4d | %s\n", article.id, article.hit, article.title);
}
}
public void showDetail(String cmd) {
String[] cmdBits = cmd.split(" ");
int id = Integer.parseInt(cmdBits[2]);
Article foundArticle = getArticleById(id);
if(foundArticle == null) {
System.out.printf("%d번 게시물은 존재하지 않습니다.\n", id);
return;
}
// 조회수 늘리기
foundArticle.increaseHit();
System.out.printf("번호 : %d\n", foundArticle.id);
System.out.printf("최초등록날짜 : %s\n", foundArticle.regDate);
System.out.printf("제목 : %s\n", foundArticle.title);
System.out.printf("내용 : %s\n", foundArticle.body);
System.out.printf("조회수 : %d\n", foundArticle.hit);
}
public void doModify(String cmd) {
String[] cmdBits = cmd.split(" ");
int id = Integer.parseInt(cmdBits[2]);
Article foundArticle = getArticleById(id);
if(foundArticle == null) {
System.out.printf("%d번 게시물은 존재하지 않습니다.\n", id);
return;
}
System.out.printf("제목 : ");
String title = sc.nextLine();
System.out.printf("내용 : ");
String body = sc.nextLine();
foundArticle.title = title;
foundArticle.body = body;
System.out.printf("%d번 게시물이 수정되었습니다.\n", id);
}
public void doDelete(String cmd) {
String[] cmdBits = cmd.split(" ");
int id = Integer.parseInt(cmdBits[2]);
int foundIndex = getArticleIndexById(id);
if(foundIndex == -1) {
System.out.printf("%d번 게시물은 존재하지 않습니다.\n", id);
return;
}
articles.remove(foundIndex);
System.out.printf("%d번 게시물이 삭제되었습니다.\n", id);
}
private int getArticleIndexById(int id) {
int i = 0;
for(Article article : articles) {
if(article.id == id) {
return i;
}
i++;
}
return -1;
}
// 공통된 기능을 하나의 메서드로 집합
private Article getArticleById(int id) {
int index = getArticleIndexById(id);
if(index != -1) {
return articles.get(index);
}
return null;
}
}
- ArticleController.java 클래스가 하는 역할은 Main 클래스에서 동작했던 articles라는 리스트를 생성하고 게시물을 등록할 때마다 해당 리스트에 게시물 정보를 저장한다.
- 추후에 게시물 관련된 기능이 추가된다면 ArticleController.java 클래스에 기능을 추가하면된다.
- 코드가 크게 바뀐 것은 없지만 Main 클래스에서 컨트롤러를 통해 ArticleController.doWrite(), ArticleController.showList(), ArticleController.showDetail(), ArticleController.doModify(), ArticleController.doDelete() 라는 메서드를 호출했을 때 값을 넘겨줄 수 있도록 메서드 명을 각 기능에 맞게 변경하여 선언하였다.
[라우팅 룰을 App에서 각각의 Controller에 위임]
- 현재까지 Article과 Member의 기능을 서로 분리하였고 모든 핵심 로직은 App.java 클래스에 담겨있다.
- 아래 코드는 현재까지 진행된 작업을 기준으로 App.java 클래스에 남아있는 코드이다.
package org.example;
import org.example.controller.ArticleController;
import org.example.controller.MemberController;
import org.example.dto.Article;
import org.example.dto.Member;
import org.example.util.Util;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class App {
private List<Article> articles;
private List<Member> members;
public App() {
articles = new ArrayList<>();
members = new ArrayList<>();
}
public void start() {
System.out.println("== 프로그램 시작 ==");
// 테스트를 위한 데이터 게시물 3개 생성
makeTestData();
Scanner sc = new Scanner(System.in);
MemberController memberController = new MemberController(sc, members);
ArticleController articleController = new ArticleController(sc, articles);
while(true) {
System.out.printf("명령어) ");
String cmd = sc.nextLine();
cmd = cmd.trim();
if(cmd.length() == 0) {
continue;
}
if(cmd.equals("system exit")) {
break;
}
else if(cmd.equals("member join")) {
memberController.doJoin();
}
else if(cmd.equals("article write")) {
articleController.doWrite();
}
else if(cmd.startsWith("article list")) {
articleController.showList(cmd);
}
// ------- 상세보기 -------
else if(cmd.startsWith("article detail ")) {
articleController.showDetail(cmd);
}
// ------- 수정 -------
else if(cmd.startsWith("article modify ")) {
articleController.doModify(cmd);
}
// ------- 삭제 -------
else if(cmd.startsWith("article delete ")) {
articleController.doDelete(cmd);
}
else {
System.out.printf("%s(은)는 존재하지 않는 명령어입니다.\n", cmd);
}
}
sc.close();
System.out.println("== 프로그램 끝 ==");
}
private void makeTestData() {
System.out.println("테스트를 위한 데이터를 생성합니다.");
articles.add(new Article(1, Util.getNowDateStr(), "제목1", "내용1", 10));
articles.add(new Article(2, Util.getNowDateStr(), "제목2", "내용2", 32));
articles.add(new Article(3, Util.getNowDateStr(), "제목3", "내용3", 103));
}
}
- 각 명령어에 대한 로직은 컨트롤러로 이전되었고, 실제로 App 클래스에서는 사용자가 입력한 명령어를 비교하는 조건문과 만약 일치한다면 각 컨트롤러에 있는 메서드를 호출한다.
- 이번에는 App 클래스에서 조건문을 통해 사용자가 입력하는 명령어를 비교하는 부분 즉, 라우팅 룰을 Article과 Member 컨트롤러로 이전시키려한다.
- 그렇게 되면 App에서 하는 일은 단순히 사용자가 입력한 명령어 중에 "article"과 "member" 만을 확인하고 각 명령어와 관련 컨트롤러로 이동하여 나머지 동작을 수행하게 된다.
- ArticleController.java 클래스에서는 switch문을 사용하여 사용자가 입력한 명령어 중 두번째 단어 즉, write, list, detail, modify, delete를 보고 케이스를 나눠 각 명령어를 받았을 때 기능을 수행하도록 한다.
- MemberController.java 클래스에서는 switch문을 사용하여 사용자가 입력한 명령어 중 두번째 단어 즉, join을 보고 케이스를 나눠 각 명령어를 받았을 때 기능을 수행하도록 한다.
- 각 컨트롤러에 대한 코드는 작성된 코드가 긴 관계로 리포지터리를 통해 참고 부탁드립니다.
반응형
'프로젝트 > [Java] 게시판 제작' 카테고리의 다른 글
[Java] 게시판 제작(11) (0) | 2024.03.10 |
---|---|
[Java] 게시판 제작(10) (0) | 2024.03.07 |
[Java] 게시판 제작(8) (0) | 2024.03.04 |
[Java] 게시판 제작(7) (0) | 2024.02.26 |
[Java] 게시판 제작(6) (0) | 2024.02.23 |