게시판 관리 App 만들기(3)

40460 단어 JAVA기초JAVA기초

22-1. 메뉴 추가하기: 회원 관리 기능 추가

MemberHandler 클래스 만들어 회원관리 기능 추가
게시판 관리와 유사하게 설정

[MemberHandler.java]

public class MemberHandler {
  static Scanner keyScan;
  static void service() {
    loop: while (true) {
      System.out.print("회원 관리> ");
      String command = keyScan.nextLine();

      switch (command) {
        case "list": break;
        case "add": break;
        case "update": break;
        case "delete": break;
        case "view": break;
        case "back":
          break loop;
        default:
          System.out.println("지원하지 않는 명령입니다.");
      }
      System.out.println();
    }
  }
}
[App.java]

...
    BoardHandler.keyScan = keyScan;
    MemberHandler.keyScan = keyScan;
    ComputeHandler.keyScan = keyScan;
...

23. 메뉴를 실행하는 핸들러의 사용 규칙을 통일하기 : 인터페이스 문법의 용도

  • 규칙 정의 : Handler
  • 규칙을 이행(implement) : BoardHandler, MemberHandler, ComputeHandler

인터페이스를 이용해 공통으로 들어갈 코드를 Handler로 따로 분리

[Handler.java]

interface Handler {
  void execute();
}
public class MemberHandler implements Handler {
  static Scanner keyScan;
  public void execute() {
...

인터페이스 상속은 implements 로 표시
상속받은 후 해당 인터페이스의 메서드 사용 가능

[App.java]
...
    BoardHandler boardHandler = new BoardHandler();
    MemberHandler memberHandler = new MemberHandler();
    ComputeHandler computeHandler = new ComputeHandler();
...
      switch (menuNo) {
        case "1":
          boardHandler.execute();
          break;
        case "2":
          memberHandler.execute();
          break;
        case "3":
          computeHandler.execute();
          break;
        case "quit":
          break menuLoop;
        default:
          System.out.println("메뉴 번호가 옳지 않습니다.");
      }
...

규칙(interface)에 따라 만든 클래스에 대해 규칙에서 정의한 메서드(execute)를 호출하려면?
-> 먼저 그 클래스의 인스턴스를 생성한 후 그 인스턴스를 이용해 메서드를 호출해야함


24. 회원 관리 기능 완성하기

  • 회원 정보를 담을 데이터 타입을 새로 설계한다. => Member
  • 회원 등록, 목록 조회, 상세 조회, 변경, 삭제 기능을 구현한다.
  • 한 개의 회원 데이터를 저장할 변수를 준비한다.
    => Member 설계도에 따라 변수를 만들고 그 주소를 리턴한다.
[MemberHandler.java]
...
  static class Member {
    String name;
    String email;
    String password;
    boolean working;
    Date registeredDate;
  }
...
    Member member = new Member();
    member.name = name;
...
    Member member = (Member) ArrayList.retrieve(index);
...

현재는 BoardHandler와 MemberHandler가 같은 ArrayList 사용
-> 두 정보가 혼합되어 저장됨 -> arraylist 분리 필요


25. 회원 데이터를 별도의 목록으로 관리하기(단순한 방법 = 유지보수가 어렵다)

  • 기존의 ArrayList 클래스를 복사하여 ArrayList2 로 만들어 사용한다.
  • MemberHandler에 있는 기존의 ArrayList를 전부 ArrayList2로 변경한다.
[MemberHandler.java]
...
    if (ArrayList2.size == ArrayList2.MAX_LENGTH) {
      System.out.println("더이상 회원을 추가할 수 없습니다.");
      return;
    }
...

26. 인스턴스 변수로 배열을 관리하기

  • ArrayList2.java 는 삭제한다.
  • ArrayList.java의 변수를 인스턴스 변수로 전환한다.
  • ArrayList의 메서드에서 인스턴스 변수를 사용할 수 있도록 인스턴스 주소를 받는 파라미터를 추가한다.
  • BoardHandler 와 MemberHandler는 각각 ArrayList 인스턴스를 생성하여 사용한다.
[ArrayList.java]

public class ArrayList {
  static final int MAX_LENGTH = 100;
  Object[] list = new Object[MAX_LENGTH];
  int size = 0;

  static void append(ArrayList that, Object obj) {
    that.list[that.size++] = obj;
  }

  static Object[] toArray(ArrayList that) {
    Object[] arr = new Object[that.size];
    for (int i = 0; i < that.size; i++) {
      arr[i] = that.list[i];
    }
    return arr;
  }

  static Object retrieve(ArrayList that, int index) {
    return that.list[index];
  }

  static void remove(ArrayList that, int index) {
    for (int i = index; i < that.size - 1; i++) {
      that.list[i] = that.list[i + 1];
    }
    that.size--;
  }
}

static final int MAX_LENGTH = 100;	

배열의 최대 크기를 지정하는 변수는 모든 인스턴스가 같음
각 인스턴스 마다 이 변수를 가질 필요XX => static변수로 선언
보통 상수 변수(final 변수)는 클래스 변수(스태틱 변수)로 선언

Object[] list = new Object[MAX_LENGTH];

각 인스턴스 마다 개별적으로 관리해야 하는 변수는 인스턴스 변수로 선언

static void append(ArrayList that, Object obj) {~~}

메서드가 작업할 때 인스턴스 변수를 사용할 수 있도록 파라미터로 인스턴스 주소를 전달


27. 인스턴스 변수를 사용하는 메서드는 인스턴스 메서드로 선언하기

ArrayList의 메서드를 클래스 메서드에서 인스턴스 메서드로 전환한다.
BoardHandler 와 MemberHandler 에서 ArrayList 의 메서드를 호출할 때 인스턴스 메서드 호출 규칙에 따라 변경한다.
인스턴스 변수(예: list, size)를 사용하는 메서드는 인스턴스 메서드를 전환한다.

[ArrayList.java]
...
  void append(Object obj) {
    this.list[this.size++] = obj;
  }

  Object[] toArray() {
    Object[] arr = new Object[this.size];
    for (int i = 0; i < this.size; i++) {
      arr[i] = this.list[i];
    }
    return arr;
  }

  Object retrieve(int index) {
    return this.list[index];
  }

  void remove(int index) {
    for (int i = index; i < this.size - 1; i++) {
      this.list[i] = this.list[i + 1];
    }
    this.size--;
  }
...

인스턴스 메서드는 인스턴스 주소를 받는 this 이름의 레퍼런스를 내장함


28. 게시판을 별도의 클래스로 추가하기(클래스를 복제해서 만들기 => 유지보수가 어렵다)

BoardHandler 를 복제하여 BoardHandler2를 만든다.

[App.java]
...
    BoardHandler2.keyScan = keyScan;
    BoardHandler2 boardHandler2 = new BoardHandler2();

    menuLoop: while (true) {
      System.out.println("[메뉴]");
      System.out.println("  1: 게시글 관리");
      System.out.println("  2: 게시글 관리2");
...
      switch (menuNo) {
        case "1":
          boardHandler.execute();
          break;
        case "2":
          boardHandler2.execute();
          break;
...

별도의 클래스로 분리하면 당장은 관리가 쉬워보이지만 여러개의 게시판이 생성될 경우 유지보수가 어려워짐


29. BoardHandler의 변수를 인스턴스 변수로 전환한다.

BoardHandler2를 삭제하고 BoardHandler의 변수를 인스턴스 변수로, 메서드도 인스턴스 메서드로 전환한다.
게시판을 구분할 때 사용할 게시판 이름을 담는 인스턴스 변수를 추가한다.

[BoardHandler.java]
...
  String boardName;
  Scanner keyScan;

  public void execute() {
    loop: while (true) {
      System.out.print(this.boardName + "/게시글 관리> ");
      String command = keyScan.nextLine();
...

게시판을 구분하기 위해 게시판 이름을 저장할 boardName인스턴스 변수 생성


30. 여러 그룹의 회원을 관리할 수 있도록 MemberHandler의 변수도 인스턴스 변수로 전환하기

MemberHandler의 스태틱 변수를 인스턴스 변수로, 메서드도 인스턴스 메서드로 전환한다.
실무에서는 가능한 향후 확장성을 고려해서 인스턴스 변수로 주로 선언하고 메서드도 인스턴스 메서드를 정의하게 된다.
ComputeHandler도 인스턴스 변수로 변경하라.

[MemberHandler.java]
...
  String memberGroupName;
  Scanner keyScan;
  
  public void execute() {
    loop: while (true) {
      System.out.print(memberGroupName + "/회원 관리> ");
[ComputeHandler.java]

public class ComputeHandler implements Handler {
  Scanner keyScan;
  ComputeHandler(Scanner keyScan) {
    this.keyScan = keyScan;
...
[App.java]
...
    BoardHandler boardHandler = new BoardHandler();
    boardHandler.keyScan = keyScan;
    boardHandler.boardName = "게시판1";

    BoardHandler boardHandler2 = new BoardHandler();
    boardHandler2.keyScan = keyScan;
    boardHandler2.boardName = "게시판2";

    MemberHandler memberHandler = new MemberHandler();
    memberHandler.keyScan = keyScan;
    memberHandler.memberGroupName = "일반회원";

    ComputeHandler computeHandler = new ComputeHandler();
    computeHandler.keyScan = keyScan;
...

31. 인스턴스를 만들 때 반드시 값을 설정하도록 강제하기

생성자 문법을 적용한다.
생성자는 인스턴스를 생성할 때 반드시 호출해야 하는 메서드이다.

[App.java]
...
 BoardHandler boardHandler = new BoardHandler("게시판1", keyScan);
    BoardHandler boardHandler2 = new BoardHandler("게시판2", keyScan);
    MemberHandler memberHandler = new MemberHandler(keyScan);
    ComputeHandler computeHandler = new ComputeHandler(keyScan);
...

좋은 웹페이지 즐겨찾기