사이먼's 코딩노트

[Java] 게시판 제작(9) 본문

프로젝트/[Java] 게시판 제작

[Java] 게시판 제작(9)

simonpark817 2024. 3. 4. 22:08

[게시판 제작 ~ing]

 

GitHub - psm817/full_stack_proj_2024_03

Contribute to psm817/full_stack_proj_2024_03 development by creating an account on GitHub.

github.com

 

[게시물 관련 기능 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