게시판 앱 업데이트
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();
}
}
기능 업데이트 등 바꾼 것은 꼭 테스트해야한다.
복제해서 만든 것의 문제점은 다 같이 복사해서 가져와야한다는 것이다.
컴파일시 인스턴스는 자동으로 this 가 달려서 넘어간다.
static 붙이느냐 마느냐의 판단은 다른 인스턴스 멤버를 사용할지에 관한
인스턴스 변수로 쓰거나 인스턴스 메소드에 쓰이느냐