Notice
Recent Posts
Recent Comments
Link
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
Tags
more
Archives
Today
Total
관리 메뉴

개발자입니다

[비트캠프] 45일차(9주차5일) - Java: myapp-08~10 본문

네이버클라우드 AIaaS 개발자 양성과정 1기/Java

[비트캠프] 45일차(9주차5일) - Java: myapp-08~10

끈기JK 2023. 1. 6. 09:14

 

08. 메뉴 구성 및 CRUD 구현

 

App이 MemberHandler 사용하고, 여기서 Prompt, Member를 사용한다.

MemberHandler의 메서드는 위와 같다.

 

### 08. 메뉴 구성 및 CRUD 구현
- 메뉴를 통해 기능 실행을 제어하는 방법
- 객체를 변경하고 삭제하는 방법
- 리팩토링 기법 연습  <- 추가

git\bitcamp-ncp\myapp\app-08 코드 참조

 

메서드 추가한다.

printMember(), getLevelText(int level), modifyMember(), deleteMember(), findByNo(int no), indexOf(Member m)

package bitcamp.myapp;

import java.sql.Date;

public class MemberHandler {

  static final int SIZE = 100;
  static int count = 0;

  // 레퍼런스 배열 준비
  static Member[] members = new Member[SIZE];

  static void inputMember() {
    Member m = new Member();
    m.no = Prompt.inputInt("번호? ");
    m.name = Prompt.inputString("이름? ");
    m.tel = Prompt.inputString("전화? ");
    m.postNo = Prompt.inputString("우편번호? ");
    m.basicAddress = Prompt.inputString("주소1? ");
    m.detailAddress = Prompt.inputString("주소2? ");
    m.working = Prompt.inputInt("0. 미취업\n1. 재직중\n재직자? ") == 1;
    m.gender = Prompt.inputInt("0. 남자\n1. 여자\n성별? ") == 0 ? 'M' : 'W';
    m.level = (byte) Prompt.inputInt("0. 비전공자\n1. 준전공자\n2. 전공자\n전공? ");
    m.createdDate = new Date(System.currentTimeMillis()).toString();

    members[count++] = m;
  }

  static void printMembers() {
    System.out.println("번호\t이름\t전화\t재직\t전공");

    for (int i = 0; i < count; i++) {
      Member m = members[i];
      System.out.printf("%d\t%s\t%s\t%s\t%s\n",
          m.no, m.name, m.tel,
          m.working ? "예" : "아니오",
              getLevelText(m.level));
    }
  }

  static void printMember() {
    int memberNo = Prompt.inputInt("회원번호? ");

    Member m = findByNo(memberNo);

    if (m == null) {
      System.out.println("해당 번호의 회원이 없습니다.");
      return;
    }

    System.out.printf("    이름: %s\n", m.name);
    System.out.printf("    전화: %s\n", m.tel);
    System.out.printf("우편번호: %s\n", m.postNo);
    System.out.printf("기본주소: %s\n", m.basicAddress);
    System.out.printf("상세주소: %s\n", m.detailAddress);
    System.out.printf("재직여부: %s\n", m.working ? "예" : "아니오");
    System.out.printf("    성별: %s\n", m.gender == 'M' ? "남자" : "여자");
    System.out.printf("    전공: %s\n", getLevelText(m.level));
    System.out.printf("  등록일: %s\n", m.createdDate);
  }

  static String getLevelText(int level) {
    switch (level) {
      case 0: return "비전공자";
      case 1: return "준전공자";
      default: return "전공자";
    }
  }

  static void modifyMember() {
    int memberNo = Prompt.inputInt("회원번호? ");

    Member old = findByNo(memberNo);

    if (old == null) {
      System.out.println("해당 번호의 회원이 없습니다.");
      return;
    }

    // 변경할 데이터를 저장할 인스턴스 준비
    Member m = new Member();
    m.no = old.no;
    m.createdDate = old.createdDate;
    m.name = Prompt.inputString(String.format("이름(%s)? ", old.name));
    m.tel = Prompt.inputString(String.format("전화(%s)? ", old.tel));
    m.postNo = Prompt.inputString(String.format("우편번호(%s)? ", old.postNo));
    m.basicAddress = Prompt.inputString(String.format("기본주소(%s)? ", old.basicAddress));
    m.detailAddress = Prompt.inputString(String.format("상세주소(%s)? ", old.detailAddress));
    m.working = Prompt.inputInt(String.format(
        "0. 미취업\n1. 재직중\n재직여부(%s)? ",
        old.working ? "재직중" : "미취업")) == 1;
    m.gender = Prompt.inputInt(String.format(
        "0. 남자\n1. 여자\n성별(%s)? ",
        old.gender == 'M' ? "남자" : "여자")) == 0 ? 'M' : 'W';
    m.level = (byte) Prompt.inputInt(String.format(
        "0. 비전공자\n1. 준전공자\n2. 전공자\n전공(%s)? ",
        getLevelText(old.level)));

    String str = Prompt.inputString("정말 변경하시겠습니까?(y/N) ");
    if (str.equalsIgnoreCase("Y")) {
      members[indexOf(old)] = m;
      System.out.println("변경했습니다.");
    } else {
      System.out.println("변경 취소했습니다.");
    }

  }

  static void deleteMember() {
    int memberNo = Prompt.inputInt("회원번호? ");

    Member m = findByNo(memberNo);

    if (m == null) {
      System.out.println("해당 번호의 회원이 없습니다.");
      return;
    }

    String str = Prompt.inputString("정말 삭제하시겠습니까?(y/N) ");
    if (!str.equalsIgnoreCase("Y")) {
      System.out.println("삭제 취소했습니다.");
      return;
    }

    for (int i = indexOf(m) + 1; i < count; i++) {
      members[i - 1] = members[i];
    }
    members[--count] = null; // 레퍼런스 카운트를 줄인다.

    System.out.println("삭제했습니다.");

  }

  static Member findByNo(int no) {
    for (int i = 0; i < count; i++) {
      if (members[i].no == no) {
        return members[i];
      }
    }
    return null;
  }

  static int indexOf(Member m) {
    for (int i = 0; i < count; i++) {
      if (members[i].no == m.no) {
        return i;
      }
    }
    return -1;
  }

  static void service() {
    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("0. 이전");
      int menuNo = Prompt.inputInt("회원관리> ");

      switch (menuNo) {
        case 0: return;
        case 1: inputMember(); break;
        case 2: printMembers(); break;
        case 3: printMember(); break;
        case 4: modifyMember(); break;
        case 5: deleteMember(); break;
        default:
          System.out.println("잘못된 메뉴 번호 입니다.");
      }
    }
  }
}

 

 

 

스태틱 메서드 vs 인스턴스 메서드

 

String.format("%s님 환영합니다!", "홍길동");  → "홍길동님 환영합니다!"

↑ 클래스.메서드(값, 값, ...) 형식이다.

String은 클래스, format은 스태틱 메서드: 문자열을 다루는 일반적인 기능 수행

 

str.charAt(3);  → 'd'

↑ 메모리.메서드(값, 값, ...) 형식이다. 메모리에 저장된 값을 사용해서 작업을 수행한다.

str은 인스턴스, charAt(3)은 인스턴스 메서드: 특정 객체에 대해 작업 수행

 

 

 

배열의 항목 삭제

 

index 3 삭제하는 상황이다.

index 4부터 한 칸씩 앞으로 이동해야 한다.

for 문을 돌리는데 i 가 마지막이면 count를 7로 변경한다.

 

 

 

09. 회원 관리 → 일반 학생 / 국비지원 학생 분리

 

회원 관리를 일반 학생/국비지원 학생으로 분리한다고 가정하자. 이때 MemberHandler 코드를 복제해서 약간만 수정하면 국비지원 학생용으로 사용할 수 있다.

그러나 이렇게 되면 MemberHandler에 기능 추가시 복제한 코드도 수정해야 한다. 복제한 코드가 100개면 100개 모두 수정해야 한다.

 

### 09. 스태틱 필드의 한계 
- 클래스 복제를 이용하여 회원을 일반 학생과 국비지원 학생으로 나눈다. 
- 클래스 복제를 이용하여 위탁교육생을 추가한다. 
- 클래스 복제 방식의 한계와 문제점 이해   
- 기능 추가/변경/삭제 할 때, 복제해서 만든 모든 코드에도 적용해야 한다.   
- 유지보수가 힘든 구조다.

git\bitcamp-ncp\myapp\app-09 코드 참조

 

MemberHandler 를 복사하여 MemberHandler2, MemberHandler3 를 만든다.

package bitcamp.myapp;

import java.sql.Date;

public class Member2Handler {

  static final int SIZE = 100;
  static int count = 0;

  static Member[] members = new Member[SIZE];

  static String title = "회원관리";

  static void inputMember() {
    Member m = new Member();
    m.no = Prompt.inputInt("번호? ");
    m.name = Prompt.inputString("이름? ");
    m.tel = Prompt.inputString("전화? ");
    m.postNo = Prompt.inputString("우편번호? ");
    m.basicAddress = Prompt.inputString("주소1? ");
    m.detailAddress = Prompt.inputString("주소2? ");
    m.working = Prompt.inputInt("0. 미취업\n1. 재직중\n재직자? ") == 1;
    m.gender = Prompt.inputInt("0. 남자\n1. 여자\n성별? ") == 0 ? 'M' : 'W';
    m.level = (byte) Prompt.inputInt("0. 비전공자\n1. 준전공자\n2. 전공자\n전공? ");
    m.createdDate = new Date(System.currentTimeMillis()).toString();

    members[count++] = m;
  }

  static void printMembers() {
    System.out.println("번호\t이름\t전화\t재직\t전공");

    for (int i = 0; i < count; i++) {
      Member m = members[i];
      System.out.printf("%d\t%s\t%s\t%s\t%s\n",
          m.no, m.name, m.tel,
          m.working ? "예" : "아니오",
              getLevelText(m.level));
    }
  }

  static void printMember() {
    int memberNo = Prompt.inputInt("회원번호? ");

    Member m = findByNo(memberNo);

    if (m == null) {
      System.out.println("해당 번호의 회원이 없습니다.");
      return;
    }

    System.out.printf("    이름: %s\n", m.name);
    System.out.printf("    전화: %s\n", m.tel);
    System.out.printf("우편번호: %s\n", m.postNo);
    System.out.printf("기본주소: %s\n", m.basicAddress);
    System.out.printf("상세주소: %s\n", m.detailAddress);
    System.out.printf("재직여부: %s\n", m.working ? "예" : "아니오");
    System.out.printf("    성별: %s\n", m.gender == 'M' ? "남자" : "여자");
    System.out.printf("    전공: %s\n", getLevelText(m.level));
    System.out.printf("  등록일: %s\n", m.createdDate);
  }

  static String getLevelText(int level) {
    switch (level) {
      case 0: return "비전공자";
      case 1: return "준전공자";
      default: return "전공자";
    }
  }

  static void modifyMember() {
    int memberNo = Prompt.inputInt("회원번호? ");

    Member old = findByNo(memberNo);

    if (old == null) {
      System.out.println("해당 번호의 회원이 없습니다.");
      return;
    }

    // 변경할 데이터를 저장할 인스턴스 준비
    Member m = new Member();
    m.no = old.no;
    m.createdDate = old.createdDate;
    m.name = Prompt.inputString(String.format("이름(%s)? ", old.name));
    m.tel = Prompt.inputString(String.format("전화(%s)? ", old.tel));
    m.postNo = Prompt.inputString(String.format("우편번호(%s)? ", old.postNo));
    m.basicAddress = Prompt.inputString(String.format("기본주소(%s)? ", old.basicAddress));
    m.detailAddress = Prompt.inputString(String.format("상세주소(%s)? ", old.detailAddress));
    m.working = Prompt.inputInt(String.format(
        "0. 미취업\n1. 재직중\n재직여부(%s)? ",
        old.working ? "재직중" : "미취업")) == 1;
    m.gender = Prompt.inputInt(String.format(
        "0. 남자\n1. 여자\n성별(%s)? ",
        old.gender == 'M' ? "남자" : "여자")) == 0 ? 'M' : 'W';
    m.level = (byte) Prompt.inputInt(String.format(
        "0. 비전공자\n1. 준전공자\n2. 전공자\n전공(%s)? ",
        getLevelText(old.level)));

    String str = Prompt.inputString("정말 변경하시겠습니까?(y/N) ");
    if (str.equalsIgnoreCase("Y")) {
      members[indexOf(old)] = m;
      System.out.println("변경했습니다.");
    } else {
      System.out.println("변경 취소했습니다.");
    }

  }

  static void deleteMember() {
    int memberNo = Prompt.inputInt("회원번호? ");

    Member m = findByNo(memberNo);

    if (m == null) {
      System.out.println("해당 번호의 회원이 없습니다.");
      return;
    }

    String str = Prompt.inputString("정말 삭제하시겠습니까?(y/N) ");
    if (!str.equalsIgnoreCase("Y")) {
      System.out.println("삭제 취소했습니다.");
      return;
    }

    for (int i = indexOf(m) + 1; i < count; i++) {
      members[i - 1] = members[i];
    }
    members[--count] = null; // 레퍼런스 카운트를 줄인다.

    System.out.println("삭제했습니다.");

  }

  static Member findByNo(int no) {
    for (int i = 0; i < count; i++) {
      if (members[i].no == no) {
        return members[i];
      }
    }
    return null;
  }

  static int indexOf(Member m) {
    for (int i = 0; i < count; i++) {
      if (members[i].no == m.no) {
        return i;
      }
    }
    return -1;
  }

  static void searchMember() {
    String name = Prompt.inputString("이름? ");

    System.out.println("번호\t이름\t전화\t재직\t전공");

    for (int i = 0; i < count; i++) {
      Member m = members[i];
      if (m.name.equalsIgnoreCase(name)) {
        System.out.printf("%d\t%s\t%s\t%s\t%s\n",
            m.no, m.name, m.tel,
            m.working ? "예" : "아니오",
                getLevelText(m.level));
      }
    }
  }

  static void service() {
    while (true) {
      System.out.println(title);
      System.out.println("1. 등록");
      System.out.println("2. 목록");
      System.out.println("3. 조회");
      System.out.println("4. 변경");
      System.out.println("5. 삭제");
      System.out.println("6. 검색");
      System.out.println("0. 이전");
      int menuNo = Prompt.inputInt(String.format("%s> ", title));

      switch (menuNo) {
        case 0: return;
        case 1: inputMember(); break;
        case 2: printMembers(); break;
        case 3: printMember(); break;
        case 4: modifyMember(); break;
        case 5: deleteMember(); break;
        case 6: searchMember(); break;
        default:
          System.out.println("잘못된 메뉴 번호 입니다.");
      }
    }
  }
}

 

package bitcamp.myapp;

import java.sql.Date;

public class Member3Handler {

  static final int SIZE = 100;
  static int count = 0;

  static Member[] members = new Member[SIZE];

  static String title = "회원관리";

  static void inputMember() {
    Member m = new Member();
    m.no = Prompt.inputInt("번호? ");
    m.name = Prompt.inputString("이름? ");
    m.tel = Prompt.inputString("전화? ");
    m.postNo = Prompt.inputString("우편번호? ");
    m.basicAddress = Prompt.inputString("주소1? ");
    m.detailAddress = Prompt.inputString("주소2? ");
    m.working = Prompt.inputInt("0. 미취업\n1. 재직중\n재직자? ") == 1;
    m.gender = Prompt.inputInt("0. 남자\n1. 여자\n성별? ") == 0 ? 'M' : 'W';
    m.level = (byte) Prompt.inputInt("0. 비전공자\n1. 준전공자\n2. 전공자\n전공? ");
    m.createdDate = new Date(System.currentTimeMillis()).toString();

    members[count++] = m;
  }

  static void printMembers() {
    System.out.println("번호\t이름\t전화\t재직\t전공");

    for (int i = 0; i < count; i++) {
      Member m = members[i];
      System.out.printf("%d\t%s\t%s\t%s\t%s\n",
          m.no, m.name, m.tel,
          m.working ? "예" : "아니오",
              getLevelText(m.level));
    }
  }

  static void printMember() {
    int memberNo = Prompt.inputInt("회원번호? ");

    Member m = findByNo(memberNo);

    if (m == null) {
      System.out.println("해당 번호의 회원이 없습니다.");
      return;
    }

    System.out.printf("    이름: %s\n", m.name);
    System.out.printf("    전화: %s\n", m.tel);
    System.out.printf("우편번호: %s\n", m.postNo);
    System.out.printf("기본주소: %s\n", m.basicAddress);
    System.out.printf("상세주소: %s\n", m.detailAddress);
    System.out.printf("재직여부: %s\n", m.working ? "예" : "아니오");
    System.out.printf("    성별: %s\n", m.gender == 'M' ? "남자" : "여자");
    System.out.printf("    전공: %s\n", getLevelText(m.level));
    System.out.printf("  등록일: %s\n", m.createdDate);
  }

  static String getLevelText(int level) {
    switch (level) {
      case 0: return "비전공자";
      case 1: return "준전공자";
      default: return "전공자";
    }
  }

  static void modifyMember() {
    int memberNo = Prompt.inputInt("회원번호? ");

    Member old = findByNo(memberNo);

    if (old == null) {
      System.out.println("해당 번호의 회원이 없습니다.");
      return;
    }

    // 변경할 데이터를 저장할 인스턴스 준비
    Member m = new Member();
    m.no = old.no;
    m.createdDate = old.createdDate;
    m.name = Prompt.inputString(String.format("이름(%s)? ", old.name));
    m.tel = Prompt.inputString(String.format("전화(%s)? ", old.tel));
    m.postNo = Prompt.inputString(String.format("우편번호(%s)? ", old.postNo));
    m.basicAddress = Prompt.inputString(String.format("기본주소(%s)? ", old.basicAddress));
    m.detailAddress = Prompt.inputString(String.format("상세주소(%s)? ", old.detailAddress));
    m.working = Prompt.inputInt(String.format(
        "0. 미취업\n1. 재직중\n재직여부(%s)? ",
        old.working ? "재직중" : "미취업")) == 1;
    m.gender = Prompt.inputInt(String.format(
        "0. 남자\n1. 여자\n성별(%s)? ",
        old.gender == 'M' ? "남자" : "여자")) == 0 ? 'M' : 'W';
    m.level = (byte) Prompt.inputInt(String.format(
        "0. 비전공자\n1. 준전공자\n2. 전공자\n전공(%s)? ",
        getLevelText(old.level)));

    String str = Prompt.inputString("정말 변경하시겠습니까?(y/N) ");
    if (str.equalsIgnoreCase("Y")) {
      members[indexOf(old)] = m;
      System.out.println("변경했습니다.");
    } else {
      System.out.println("변경 취소했습니다.");
    }

  }

  static void deleteMember() {
    int memberNo = Prompt.inputInt("회원번호? ");

    Member m = findByNo(memberNo);

    if (m == null) {
      System.out.println("해당 번호의 회원이 없습니다.");
      return;
    }

    String str = Prompt.inputString("정말 삭제하시겠습니까?(y/N) ");
    if (!str.equalsIgnoreCase("Y")) {
      System.out.println("삭제 취소했습니다.");
      return;
    }

    for (int i = indexOf(m) + 1; i < count; i++) {
      members[i - 1] = members[i];
    }
    members[--count] = null; // 레퍼런스 카운트를 줄인다.

    System.out.println("삭제했습니다.");

  }

  static Member findByNo(int no) {
    for (int i = 0; i < count; i++) {
      if (members[i].no == no) {
        return members[i];
      }
    }
    return null;
  }

  static int indexOf(Member m) {
    for (int i = 0; i < count; i++) {
      if (members[i].no == m.no) {
        return i;
      }
    }
    return -1;
  }

  static void searchMember() {
    String name = Prompt.inputString("이름? ");

    System.out.println("번호\t이름\t전화\t재직\t전공");

    for (int i = 0; i < count; i++) {
      Member m = members[i];
      if (m.name.equalsIgnoreCase(name)) {
        System.out.printf("%d\t%s\t%s\t%s\t%s\n",
            m.no, m.name, m.tel,
            m.working ? "예" : "아니오",
                getLevelText(m.level));
      }
    }
  }

  static void service() {
    while (true) {
      System.out.println(title);
      System.out.println("1. 등록");
      System.out.println("2. 목록");
      System.out.println("3. 조회");
      System.out.println("4. 변경");
      System.out.println("5. 삭제");
      System.out.println("6. 검색");
      System.out.println("0. 이전");
      int menuNo = Prompt.inputInt(String.format("%s> ", title));

      switch (menuNo) {
        case 0: return;
        case 1: inputMember(); break;
        case 2: printMembers(); break;
        case 3: printMember(); break;
        case 4: modifyMember(); break;
        case 5: deleteMember(); break;
        case 6: searchMember(); break;
        default:
          System.out.println("잘못된 메뉴 번호 입니다.");
      }
    }
  }
}

 

 

 

클래스를 복제하는 방식으로 메뉴 추가하기

 

 

문제점

  • 기능 추가할 때 복제한 모든 클래스를 변경해야 한다.
  • 버그 발생시 복제한 모든 클래스에 대해 변경해야 한다.

→ 유지보수가 매우 힘들다.

 

 

 

10. 스태틱 멤버 → 인스턴스 멤버 전환, 생성자 도입

 

생성자: 인스턴스 생성에 필요한 값을 받는다. 인스턴스 사용하기 전에 유효한 값으로 채운다.

인스턴스 필드 : 개별적으로 다뤄야 할 데이터

인스턴스 메서드 : 인스턴스 멤버(필드, 메서드) 사용

생성자 : 인스턴스 필드의 필수 값 받을 때 유용

 

### 10. 인스턴스 필드와 인스턴스 메서드 사용법, 생성자 사용법  
- MemberHandler의 스태틱 필드를 인스턴스 필드로 변경 
- MemberHandler의 스태틱 메서드를 인스턴스 메서드로 변경 
- MemberHandler에서 프롬프트 제목을 다룰 수 있게 변경 
- 생성자를 도입하여 title 필드를 필수 입력으로 설정

 

package bitcamp.myapp;

public class App {

  public static void main(String[] args) {
    goMainMenu();
    System.out.println("안녕히 가세요!");

    // 프로그램이 사용한 자원 해제하기
    Prompt.close();
  } // main()

  private static void goMainMenu() {
    // 일반 학생 목록을 저장할 메모리를 준비한다.
    MemberHandler generalMemberHandler = new MemberHandler("일반학생");

    // 국비지원 학생 목록을 저장할 메모리를 준비한다.
    MemberHandler supportedMemberHandler = new MemberHandler("국비지원학생");

    // 기업 위탁 교육생 목록을 저장할 메모리를 준비한다.
    MemberHandler companyMemberHandler = new MemberHandler("위탁교육생");

    // 게시글 목록을 저장할 메모리를 준비한다.
    BoardHandler boardHandler = new BoardHandler("게시판");

    while (true) {
      System.out.println("1. 일반학생관리");
      System.out.println("2. 국비지원학생관리");
      System.out.println("3. 위탁교육생관리");
      System.out.println("4. 게시판");
      System.out.println("9. 종료");
      int menuNo = Prompt.inputInt("메뉴> ");

      if (menuNo == 1) {
        generalMemberHandler.service();

      } else if (menuNo == 2) {
        supportedMemberHandler.service();

      } else if (menuNo == 3) {
        companyMemberHandler.service();

      } else if (menuNo == 4) {
        boardHandler.service();

      } else if (menuNo == 9) {
        break;
      } else {
        System.out.println("잘못된 메뉴 번호 입니다.");
      }
    }
  }

} // class App

 

package bitcamp.myapp;

public class Board {
  int no;
  String title;
  String content;
  String password;
  String createdDate;
  int viewCount;
}

 

package bitcamp.myapp;

import java.sql.Date;

public class BoardHandler {

  // 모든 인스턴스가 공유하는 데이터를 스태틱 필드로 만든다.
  // 특히 데이터를 조회하는 용으로 사용하는 final 변수는 스태틱 필드로 만들어야 한다.
  static final int SIZE = 100;

  int count;
  Board[] boards = new Board[SIZE];
  String title;

  // 인스턴스를 만들 때 프롬프트 제목을 반드시 입력하도록 강제한다.
  BoardHandler(String title) {
    this.title = title;
  }

  void inputBoard() {
    Board b = new Board();
    b.no = Prompt.inputInt("번호? ");
    b.title = Prompt.inputString("제목? ");
    b.content = Prompt.inputString("내용? ");
    b.password = Prompt.inputString("암호? ");
    b.createdDate = new Date(System.currentTimeMillis()).toString();

    this.boards[count++] = b;
  }

  void printBoards() {
    System.out.println("번호\t제목\t작성일\t조회수");

    for (int i = 0; i < this.count; i++) {
      Board b = this.boards[i];
      System.out.printf("%d\t%s\t%s\t%d\n",
          b.no, b.title, b.createdDate, b.viewCount);
    }
  }

  void printBoard() {
    int boardNo = Prompt.inputInt("게시글 번호? ");

    Board b = this.findByNo(boardNo);

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

    System.out.printf("    제목: %s\n", b.title);
    System.out.printf("    내용: %s\n", b.content);
    System.out.printf("  등록일: %s\n", b.createdDate);
    System.out.printf("  조회수: %d\n", b.viewCount++);
  }

  void modifyBoard() {
    int boardNo = Prompt.inputInt("게시글 번호? ");

    Board old = this.findByNo(boardNo);

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

    // 변경할 데이터를 저장할 인스턴스 준비
    Board b = new Board();
    b.no = old.no;
    b.createdDate = old.createdDate;
    b.title = Prompt.inputString(String.format("제목(%s)? ", old.title));
    b.content = Prompt.inputString(String.format("내용(%s)? ", old.content));
    b.password = Prompt.inputString("암호? ");

    if (!old.password.equals(b.password)) {
      System.out.println("암호가 맞지 않습니다!");
      return;
    }

    String str = Prompt.inputString("정말 변경하시겠습니까?(y/N) ");
    if (str.equalsIgnoreCase("Y")) {
      this.boards[this.indexOf(old)] = b;
      System.out.println("변경했습니다.");
    } else {
      System.out.println("변경 취소했습니다.");
    }

  }

  void deleteBoard() {
    int boardNo = Prompt.inputInt("게시글 번호? ");

    Board b = this.findByNo(boardNo);

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

    String password = Prompt.inputString("암호? ");
    if (!b.password.equals(password)) {
      System.out.println("암호가 맞지 않습니다!");
      return;
    }

    String str = Prompt.inputString("정말 삭제하시겠습니까?(y/N) ");
    if (!str.equalsIgnoreCase("Y")) {
      System.out.println("삭제 취소했습니다.");
      return;
    }

    for (int i = this.indexOf(b) + 1; i < this.count; i++) {
      this.boards[i - 1] = this.boards[i];
    }
    this.boards[--this.count] = null; // 레퍼런스 카운트를 줄인다.

    System.out.println("삭제했습니다.");

  }

  Board findByNo(int no) {
    for (int i = 0; i < this.count; i++) {
      if (this.boards[i].no == no) {
        return this.boards[i];
      }
    }
    return null;
  }

  int indexOf(Board b) {
    for (int i = 0; i < this.count; i++) {
      if (this.boards[i].no == b.no) {
        return i;
      }
    }
    return -1;
  }

  void searchBoard() {
    String keyword = Prompt.inputString("검색어? ");

    System.out.println("번호\t제목\t작성일\t조회수");

    for (int i = 0; i < this.count; i++) {
      Board b = this.boards[i];
      if (b.title.indexOf(keyword) != -1 ||
          b.content.indexOf(keyword) != -1) {
        System.out.printf("%d\t%s\t%s\t%d\n",
            b.no, b.title, b.createdDate, b.viewCount);
      }
    }
  }

  void service() {
    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("6. 검색");
      System.out.println("0. 이전");
      int menuNo = Prompt.inputInt(String.format("%s> ", this.title));

      switch (menuNo) {
        case 0: return;
        case 1: this.inputBoard(); break;
        case 2: this.printBoards(); break;
        case 3: this.printBoard(); break;
        case 4: this.modifyBoard(); break;
        case 5: this.deleteBoard(); break;
        case 6: this.searchBoard(); break;
        default:
          System.out.println("잘못된 메뉴 번호 입니다.");
      }
    }
  }
}

 

 

 


 

조언

 

*

 

 

 


 

과제

 

게시글 관리 기능 추가

 

 

저녁 학습

com.eomcs.oop.ex04