게시판 앱 업데이트

Board

package com.bitcamp.board;

public class Board {
  // 인스턴스를 생성할 때 준비되는 메모리를 선언
  int no;
  String title;
  String content;
  String writer;
  String password;
  int viewCount;
  long createdDate;
}

App

/*
 * 게시판 관리 애플리케이션
 * 비트캠프-20220704
 */
package com.bitcamp.board;

public class App {

  public static void main(String[] args) {
    welcome();

    // 인스턴스를 생성할 때 생성자가 원하는 값을 반드시 줘야 한다.
    // 주지 않으면 컴파일 오류이다!
    //
    BoardHandler boardHandler = new BoardHandler("게시판");
    BoardHandler readingHandler = new BoardHandler("독서록");
    BoardHandler visitHandler = new BoardHandler("방명록");
    BoardHandler noticeHandler = new BoardHandler("공지사항");
    BoardHandler diaryHandler = new BoardHandler("일기장");

    loop: while (true) {

      // 메인 메뉴 출력
      System.out.println("메뉴:");
      System.out.println("  1: 게시판");
      System.out.println("  2: 독서록");
      System.out.println("  3: 방명록");
      System.out.println("  4: 공지사항");
      System.out.println("  5: 일기장");
      System.out.println();
      int mainMenuNo = Prompt.inputInt("메뉴를 선택하세요[1..4](0: 종료) ");

      switch (mainMenuNo) {
        case 0: break loop;
        case 1: // 게시판
          boardHandler.execute();
          break;
        case 2: // 독서록
          readingHandler.execute();
          break;
        case 3: // 방명록
          visitHandler.execute();
          break;
        case 4: // 공지사항
          noticeHandler.execute();
          break;
        case 5: // 일기장
          diaryHandler.execute();
          break;
        default: System.out.println("메뉴 번호가 옳지 않습니다!");
      } // switch

    } // while

    System.out.println("안녕히 가세요!");
    Prompt.close();
  } // main

  static void welcome() {
    System.out.println("[게시판 애플리케이션]");
    System.out.println();
    System.out.println("환영합니다!");
    System.out.println();
  }
}

BoardHandler

/*
 * 게시글 메뉴 처리 클래스
 */
package com.bitcamp.board;

import java.text.SimpleDateFormat;
import java.util.Date;

public class BoardHandler {

  String title; // 게시판의 제목

  // 게시글 목록을 관리할 객체 준비
  BoardList boardList = new BoardList();

  public BoardHandler() {
    this.title = "게시판";
  }

  BoardHandler(String title) {
    this.title = title;
  }

  void execute() {
    while (true) {
      System.out.printf("%s:\\n", this.title);
      System.out.println("  1: 목록");
      System.out.println("  2: 상세보기");
      System.out.println("  3: 등록");
      System.out.println("  4: 삭제");
      System.out.println("  5: 변경");
      System.out.println();

      int menuNo = Prompt.inputInt("메뉴를 선택하세요[1..5](0: 이전) ");
      displayHeadline();

      // 다른 인스턴스 메서드를 호출할 때 this에 보관된 인스턴스 주소를 사용한다. 
      switch (menuNo) {
        case 0: return;
        case 1: this.onList(); break;
        case 2: this.onDetail(); break;
        case 3: this.onInput(); break;
        case 4: this.onDelete(); break;
        case 5: this.onUpdate(); break;
        default: System.out.println("메뉴 번호가 옳지 않습니다!");
      }

      displayBlankLine();
    } // 게시판 while
  }

  static void displayHeadline() {
    System.out.println("=========================================");
  }

  static void displayBlankLine() {
    System.out.println(); // 메뉴를 처리한 후 빈 줄 출력
  }

  void onList() {
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

    System.out.printf("[%s 목록]\\n", this.title);
    System.out.println("번호 제목 조회수 작성자 등록일");

    // boardList 인스턴스에 들어 있는 데이터 목록을 가져온다.
    Board[] list = this.boardList.toArray();

    for (Board board : list) {
      Date date = new Date(board.createdDate);
      String dateStr = formatter.format(date); 
      System.out.printf("%d\\t%s\\t%d\\t%s\\t%s\\n",
          board.no, board.title, board.viewCount, board.writer, dateStr);
    }

  }

  void onDetail() {
    System.out.printf("[%s 상세보기]\\n", this.title);

    int boardNo = Prompt.inputInt("조회할 게시글 번호? ");

    // 해당 번호의 게시글이 몇 번 배열에 들어 있는지 알아내기
    Board board = this.boardList.get(boardNo);

    // 사용자가 입력한 번호에 해당하는 게시글을 못 찾았다면
    if (board == null) {
      System.out.println("해당 번호의 게시글이 없습니다!");
      return;
    }

    System.out.printf("번호: %d\\n", board.no);
    System.out.printf("제목: %s\\n", board.title);
    System.out.printf("내용: %s\\n", board.content);
    System.out.printf("조회수: %d\\n", board.viewCount);
    System.out.printf("작성자: %s\\n", board.writer);
    Date date = new Date(board.createdDate);
    System.out.printf("등록일: %tY-%1$tm-%1$td %1$tH:%1$tM\\n", date);

  }

  void onInput() {
    System.out.printf("[%s 등록]\\n", this.title);

    Board board = new Board();

    board.title = Prompt.inputString("제목? ");
    board.content = Prompt.inputString("내용? ");
    board.writer = Prompt.inputString("작성자? ");
    board.password = Prompt.inputString("암호? ");
    board.viewCount = 0;
    board.createdDate = System.currentTimeMillis();

    this.boardList.add(board);

    System.out.println("게시글을 등록했습니다.");
  }

  void onDelete() {
    System.out.printf("[%s 삭제]\\n", this.title);

    int boardNo = Prompt.inputInt("삭제할 게시글 번호? ");

    if (boardList.remove(boardNo)) {
      System.out.println("삭제하였습니다.");
    } else {
      System.out.println("해당 번호의 게시글이 없습니다!");
    }
  }

  void onUpdate() {
    System.out.printf("[%s 변경]\\n", this.title);

    int boardNo = Prompt.inputInt("변경할 게시글 번호? ");

    Board board = this.boardList.get(boardNo);

    if (board == null) {
      System.out.println("해당 번호의 게시글이 없습니다!");
      return;
    }

    String newTitle = Prompt.inputString("제목?(" + board.title + ") ");
    String newContent = Prompt.inputString(String.format("내용?(%s) ", board.content));

    String input = Prompt.inputString("변경하시겠습니까?(y/n) ");
    if (input.equals("y")) {
      board.title = newTitle;
      board.content = newContent;
      System.out.println("변경했습니다.");
    } else {
      System.out.println("변경 취소했습니다.");
    }
  }
}

BoardList

package com.bitcamp.board;

// 게시글 목록을 관리하는 역할
//
public class BoardList {

  static final int DEFAULT_SIZE = 3;

  int boardCount; 
  Board[] boards; 
  int no = 0;

  // 생성자
  BoardList() {
    this.boards = new Board[DEFAULT_SIZE];
  }

  BoardList(int initCapacity) {
    this.boards = new Board[initCapacity];
  }

  // 목록에 저장된 인스턴스를 꺼내서 리턴한다.
  Board[] toArray() {
    Board[] arr = new Board[this.boardCount];
    for (int i = 0; i < arr.length; i++) {
      arr[i] = this.boards[i];
    }
    return arr;
  }

  // 게시글 번호에 해당하는 Board 인스턴스를 찾아 리턴한다.
  Board get(int boardNo) {
    for (int i = 0; i < this.boardCount; i++) {
      if (this.boards[i].no == boardNo) {
        return this.boards[i];
      }
    }
    return null;
  }

  // Board 인스턴스를 배열에 저장한다.
  void add(Board board) {
    if (this.boardCount == this.boards.length) {
      grow();
    }
    board.no = nextNo();
    this.boards[this.boardCount++] = board;
  }

  boolean remove(int boardNo) {
    int boardIndex = -1;
    for (int i = 0; i < this.boardCount; i++) {
      if (this.boards[i].no == boardNo) {
        boardIndex = i;
        break;
      }
    }

    if (boardIndex == -1) {
      return false;
    }

    // 삭제할 항목의 다음 항목을 앞으로 당긴다.
    for (int i = boardIndex + 1; i < this.boardCount; i++) {
      this.boards[i - 1] = this.boards[i];
    }

    // 게시글 개수를 한 개 줄인 후 
    // 맨 뒤의 있던 항목의 주소를 0으로 설정한다.
    this.boards[--this.boardCount] = null;

    return true;
  }

  void grow() {
    int newSize = this.boards.length + (this.boards.length >> 1);
    Board[] newArray = new Board[newSize];
    for (int i = 0; i < this.boards.length; i++) {
      newArray[i] = this.boards[i];
    }
    this.boards = newArray;
  }

  int nextNo() {
    return ++no;
  }
}

Prompt

/*
 * 키보드 입력을 받는 도구를 구비하고 있다.
 */
package com.bitcamp.board;

public class Prompt {

  static java.util.Scanner keyboardInput = new java.util.Scanner(System.in);

  static int inputInt() {
    String str = keyboardInput.nextLine();
    return Integer.parseInt(str); //"123" ==> 123, "5" ==> 5, "ok" ==> 실행 오류!
  }

  static int inputInt(String title) {
    System.out.print(title);
    String str = keyboardInput.nextLine();
    return Integer.parseInt(str); 
  }

  static String inputString() {
    return keyboardInput.nextLine();
  }

  static String inputString(String title) {
    System.out.print(title);
    return keyboardInput.nextLine();
  }

  static void close() {
    keyboardInput.close();
  }
}