사이먼's 코딩노트

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

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

[Java] 게시판 제작(6)

simonpark817 2024. 2. 23. 17:03

[게시판 제작 ~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

 

[중복되는 코드 메서드로 묶어 제거하기]

Article foundArticle = null;

for(int i = 0; i < articles.size(); i++) {
    Article article = articles.get(i);

    if(article.id == id) {
        foundArticle = article;
        break;
    }
}
  • 위 코드와 같이 현재까지 구현된 코드를 보면 "article detail", "article modify", "article delete" 명령어를 입력했을 때 사용자가 입력한 고유 번호와 articles에서 get한 각 게시물의 고유 번호가 일치하면 기능별로 수행하도록 했다.
  • 이 과정에서 같은 코드를 여러번 반복 사용하여 코드의 가독성이나 효율성이 떨어지게됐다.

 

  • 이번에는 중복되는 코드들을 하나의 메서드로 묶어서 최소화하는 것을 구현해봅시다.
private static Article getArticleById(int id) {
    for(int i = 0; i < articles.size(); i++) {
        Article article = articles.get(i);

        if(article.id == id) {
            return article;
        }
    }

    return null;
}
  • getArticleById() 메서드는 기존에 있던 코드를 하나의 메서드화하여 다시 작성한 코드이다. 이 메서드의 역할은 "article detail", "article modify", "article delete" 명령어에서 명령어 뒤에 입력하는 게시물의 고유 번호를 인자로 받아 사용자가 입력한 게시물 번호를 통해 해당 게시물을 가져온다.

 

private static Article getArticleById(int id) {
    // articles가 있는 경우 모두 반복
    for(Article article : articles) {
        if(article.id == id) {
            return article;
        }
    }
    return null;
}
  • 해당 메서드를 향상된 for문으로 바꿔서 작성하면 위와 같은 코드가 만들어진다.
  • for(Article article : articles) 는 articles에 게시물이 있는 경우 해당 개수만큼 계속 반복한다는 의미이다.
  • 다시 말해 게시물 article을 articles가 있을 때까지 차례대로 반복하면서 입력한 번호와 게시물의 공유 번호가 같다면 해당 게시물(article)을 return 한다.

 

  • 하지만, "article delete"의 경우 "article detail", "article modify" 와는 다르게 게시물 자체가 아닌 단지 고유 번호(인덱스 번호)만 필요로 하기 때문에 새로운 메서드가 하나 추가되어야 한다.
private static int getArticleIndexById(int id) {
    int i = 0;
    for(Article article : articles) {
        if(article.id == id) {
            return i;
        }
        i++;
    }

    return -1;
}
  • getArticleIndexById() 메서드는 getArticleById() 메서드와는 거의 유사하지만 id 즉 고유 번호만을 반환하는 역할을 한다.
  • 마찬가지로 향상된 for문을 사용하였고, 만약 고유 번호가 같은 게시물을 찾아냈다면 이번에는 해당 게시물(article) 자체가 아닌 그 게시물이 articles 배열의 몇 번째인지 인덱스 번호를 return 값으로 준다.
  • index의 초기값이 0인 이유는 배열의 인덱스 번호가 0부터 시작하기 때문이다. 

 

  • 여기서 또 한번 고민되는 부분은 getArticleById()와 getArticleIndexById() 메서드가 서로 유사하기 때문에 이것도 코드를 간소화가 가능하다면 간소화를 시키는 것이 좋다.
private static int getArticleIndexById(int id) {
    int i = 0;
    for(Article article : articles) {
        if(article.id == id) {
            return i;
        }
        i++;
    }

    return -1;
}

private static Article getArticleById(int id) {
    int index = getArticleIndexById(id);

    if(index != -1) {
       return articles.get(index);
    }

    return null;
}
  • 위 코드는 특정 게시물을 찾는 메서드를 구현한 후 관련 중복을 모두 제거한 최종 코드이다.
  • Index 즉, 고유 번호만 구해오면 게시물의 정보를 알 수 있기 때문에 getArticleById() 메서드에서 index 라는 변수를 생성해주고 해당 index를 getArticleIndexById() 메서드에서 인덱스 번호를 가져오면 된다.
  • 이렇게 되면 index 값을 조건에 맞춰 getArticleIndexById() 메서드에서 반환해주고 만약 index가 -1이면 게시물이 없다고 Main 메서드에게 반환하고 -1이 아닐 경우 해당 고유 번호 값에 맞춰 articles에서 게시물을 get한다.

 

[게시물 리스트에 검색기능 추가]

  • 다음은 "article list" 명령어 뒤에 문자나 숫자를 입력해서 해당 문구가 포함하는 게시물의 제목이 있다면 해당 게시물만 리스팅하여 보여주는 검색 기능을 추가해봅시다.
else if(cmd.startsWith("article list")) {
    if(articles.size() == 0) {
        System.out.println("게시물이 없습니다.");
        continue;
    }

    List<Article> forListArticles = articles;

    String searchKeyword = cmd.substring("article list".length()).trim();

    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.printf("검색결과(%s)가 존재하지 않습니다.\n", searchKeyword);
    }


    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);
    }

}
  • 먼저 Main 클래스에서 선언했던 articles 배열에 연결할 forListArticles 라는 변수를 생성해준다.
  • forListArticles에 들어간 게시물은 articles에 들어있는 게시물과 동일하지만, 나중에 검색어가 포함된 게시물이 있다면 해당 게시물을 새로 담아줄 새로운 ArrayList 객체를 생성한다.
  • 다시 말해 검색어가 없다면 forListArticles은 articles과 완전 정보를 담고있는 배열이다.
  • 사용자가 입력하는 검색어 searchKeyword는 "article list" 뒤에 오는 문자이기 때문에 이것도 역시 split() 메서드와 같이 문자를 구분해주는 메서드를 사용해야한다.
  • 지금과 같이 문자 string 타입일 경우에는 substring을 사용한다. [cmd.substring("article list".length()).trim()]
  • 여기서 substring() 메서드는 매개변수로 시작 인덱스 번호를 받고, 해당 인덱스 번호부터 뒤에 나오는 모든 문자열을 추출한다. "article list" 라는 문자열의 길이는 총 13이여서 substring(13) 이라고 했어도 문제는 없겠지만, 만약 사용자가 "article list" 문구를 다르게 바꿔버리면 13이라는 길이가 무의미해지기 때문에 ("article.list".length()).trim()과 같이 article list의 양옆 공백을 포함하여 해당 문자열의 길이를 인자로 넘겨줬다. 
  • 만약 입력한 검색어 searchKeyword의 길이가 0 이상 즉, 검색어가 있을 경우 검색어가 포함된 게시물을 담아줄 forListArticles 변수에 ArrayList 객체를 새로 생성한다.
  • 그리고 저장된 articles의 개수만큼 반복문을 통해 게시물의 제목에 searchKeyword가 포함되어 있다면 forListArticles에 해당 게시물을 저장(add)한다. 
  • 마지막으로 검색어가 포함된 게시물이 없는 경우에는 검색결과가 존재하지 않는다는 출력문을 출력한다.

 

  • 현재까지 작성된 코드를 실행하면 다음과 같이 게시판이 동작한다.

게시판 6차 동작

 

반응형

'프로젝트 > [Java] 게시판 제작' 카테고리의 다른 글

[Java] 게시판 제작(8)  (0) 2024.03.04
[Java] 게시판 제작(7)  (0) 2024.02.26
[Java] 게시판 제작(5)  (0) 2024.02.22
[Java] 게시판 제작(4)  (0) 2024.02.21
[Java] 게시판 제작(3)  (0) 2024.02.21