게시판 작성 주석

sungsimdangmascot·2026년 4월 12일
//프로그램 시작과 종료
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    System.out.println("== 프로그램 시작 ==");
    Scanner sc = new Scanner(System.in);

    int lastArticleId = 0; // 작성되는 게시글들을 1번부터 발급.
    int lastMemberId = 0; // 작성되는 회원번호는 1번부터 발급.

    List<Article> articles = new ArrayList<>(); //게시글을 담을 상자
    List<Member> members = new ArrayList<>(); // 회원 정보를 담을 상자

    //List 제너릭 괄호 기호 오류, <> 로 변경해야 한다.

    while (true) {
      System.out.print("명령어 ) ");
      String cmd = sc.nextLine().trim();

      //컴퓨터는 같은 단어여도 공백 유무에 따라 다르게 판단한다.
      // 따라서 실수 없이 같은 값을 보여주기 위해 앞 뒤 공백을 제거해주는 trim();을 사용해야 한다.
      //문자열이 필요하므로 split()은 불필요하다. 사용시에는 ()안에 기준값 넣어야 한다.

      if (cmd.length() == 0) {
        System.out.println("명령어를 입력해주세요");
        // 아무것도 입력하지 않았을 때의 출력문은 맨 위로 올리는 것이 좋다.
        continue;
      }

      if (cmd.equals("exit")) {
        break; // 프로그래밍 종료
      }

      // =======================================================
      // [1] 회원 가입 (member join) - 새로 추가된 기능
      // =======================================================
      else if (cmd.equals("member join")) {
        System.out.println("== 회원 가입 ==");
        String loginId;
        String loginPw;
        String name;

        // 밑에 정보들을 저장하기 위해 만든것들을 임시로 보관해두는 용도.
        // 자바는 한번에 클래스로 옮길 수 없다. 그래서 임시 보관함을 통한 다음 옮긴다.

        // 아이디 입력 및 중복 체크
        while (true) {

          //올바른 아이디를 칠 때까지 물어본다.
          System.out.print("로그인 아이디 : ");
          loginId = sc.nextLine().trim();

          //위에 상자를 넣어놔서 상자 이름만 말하면되서 문자열 표시하지 않음

          boolean isJoinableId = true;

          //무죄추정 원칙처럼 true라고 가정하고 밑 조건들을 본 다음 최종적으로 참 거짓 여부를 바꾼다.
          //자바에서는 {} 안에서 태어난 변수는 {} 가 끝날 때 같이 죽으므로,
          //검사를 다 마친 후 최종본을 알아야 하므로 조건문 전에 입력한다.

          for (Member member : members) {

            //회원 명부를 끝까지 다 뒤지는 타입.

            //members : 뒤져볼 전체 회원 명부 리스트
            // : 콜론은 오른쪽 명부에서 하나씩 꺼내서 왼쪽에 담으라는 기호
            // Member memebr은 명부에서 꺼낸 회원 한명을 잠깐 쥐고 있을 변수이다.
            //많은 데이터를 하나씩 뽑을 때 주로 사용한다.

            if (member.getLoginId().equals(loginId)) {

              //member.getLoginId()는 기존 장부에 있던 기존 회원 아이디이다.
              //loginId 는 비교대상으로 새로 가입할는 아이디이다.
              //. 의 뜻 : 손에 있는 리모컨(member)의 버튼(.)을 눌러서, 창고에 있는 진짜 본체의 아이디를 가져와(getLoginId)라는 뜻.

              isJoinableId = false;

              //두 개가 같으면 새로 가입할 의미가 없기에 거짓이라 한다.
              //boolean isJoinableId = true; 위에 이 코드를 끄는것.
              break;
              // 현재 돌고 있는 반복문을 꺠고 밖으로 탈출해라.
            }
          }

          if (isJoinableId == false) {
            System.out.printf("%s(은)는 이미 사용중인 아이디입니다.\n", loginId);

            //위에 출력문을 쓰지 않고 여기에 다시 쓴 이유 :  밑에 비밀번호를 입력이 있으므로
            //만약 위에 출력문을 적었다면 출력만 하고 그대로 가입 절차를 진행시키는 버그가 생김.
            //그래서

            continue;
            //밑으로 더 내려가지 말고 반복문 맨 위로 올라가서 처음부터 다시 시작해.
            //방금 입력한 아이디는 이미 다른 사람이 쓰고 있어서 쓸 수 없으니, 새로운 아이디를 다시 생각해서 적으라고 기회를 주는 것.

            //위 출력문을 여기에 적은 이유는 위에 출력문을 적었다면, 거짓 판명나서 break;로 나와서 바로 다음 비밀번호 단계로 내려가기에,
            //다시 위로 올려보내기 위해 이 조건문을 적어 확인하고 continue로 다시 위로 돌려보낸다.
            // 위에break 대신 continue를 쓰는 이유는 이 코드는 중복된 아이디 발견시 바로 종료하면 된다.
            // 굳이 뒤에 id까지 검사할 필요가 없기에 이렇게 하는 것이 더 효율적이다.
          }
          break;

          //id 단계 해결
          //while문 종료.
        }

        // 비밀번호 입력 및 확인
        while (true) {
          System.out.print("로그인 비번 : ");
          loginPw = sc.nextLine().trim();
          System.out.print("로그인 비번 확인 : ");
          String loginPwConfirm = sc.nextLine().trim();

          if (loginPw.equals(loginPwConfirm) == false) {
            System.out.println("비밀번호가 일치하지 않습니다. 다시 입력해주세요.");
            continue;
          }
          break;
        }

        System.out.print("이름 : ");
        name = sc.nextLine().trim();

        int id = lastMemberId + 1;

        //새 회원에게 고유 번호를 발급해 준다.
        //컴퓨터 전용 불변의 번호가 필요하기 때문이다. -> 아디디 변경을 할 때 로그인 아이디로만 했다면
        //그동안의 모든 것들을 다 뒤져서 해야하지만 컴퓨터 아이디로 하면, 겉으로 본이는 아이디나 이름이 바뀌어도
        //컴퓨터는 아 이 번호의 회원이 바꾼거라고 인식하여서 헷갈리지 않음.

        String regDate = Util.getNowStr();

        //String regDate: 가입 날짜를 적어둘 빈칸을 준비하라는 뜻이다.
        //Util: 다른 곳에 class Util이라고 도우미 클래스를 따로 만들어 두었다.)
        //.getNowStr(): util 도구 상자 안에 있는 기능이다.
        // 지금 당장(Now)의 시간을 글자(String)로 가져와(get)!"라는 뜻이다.

        Member member = new Member(id, regDate, regDate, loginId, loginPw, name);

        //메모리에 새로운 공간을 만들고, 거기에 데이터를 채워 넣는 과정이다.
        //new Member(...): new 키워드는 메모리의 빈 공간을 확보하라는 직접적인 명령이다.
        //확보한 공간에 Member 클래스에 적혀있는 모양대로 틀을 잡는다.
        //그리고 괄호 안에 있는 6개의 변수(id, regDate...) 값들을 그 틀 안의 빈칸에 각각 대입한다.
        //이때 this.id = id; 코드가 실행되는 것이다.

        //regDate, regDate가 두 번 들어간 이유:
        //Member 클래스의 생성자는 6개의 인자(인풋)를 받도록 설계되어 있다.
        //순서대로 번호, 가입일, 수정일, 아이디, 비밀번호, 이름이다.
        //지금은 최초 가입 시점이므로 '수정일'이 따로 존재할 수 없다.
        //따라서 가입일과 동일한 데이터(regDate)를 두 번째와 세 번째 자리에 연속으로 넘겨주어 문법적 오류를 막고 데이터를 채운 것이다.

        //Member member =:
        //방금 메모리에 만들어진 데이터 덩어리(객체)를 코드에서 조종할 때 필요한 것.
        //member라는 이름의 변수(참조 변수)를 만들어서, 방금 만들어진 메모리 공간의 주소(위치)를 저장해 두는 것이다.
        //이제 member라는 이름만 부르면 그 데이터 덩어리에 접근할 수 있다.

        //참조변수 : 거대한 물건(본체)을 직접 들고 있는 게 아니라,
        //         그 물건을 조종할 수 있는 리모컨(주소)만 담아둔 주머니

        members.add(member);

        //방금 메모리에 생성한 새 회원 데이터(member)를,
        //전체 회원을 관리하는 'members 리스트(배열)'의 맨 마지막 칸에 저장하는 명령어

        System.out.printf("%d번 회원이 가입되었습니다.\n", id);
        lastMemberId++;

        // 가입 성공으로 발급한 번호를 공식적으로 1 올려놓으라는 명령어
      }

      // =======================================================
      // [2] 게시글 작성 (article write)
      // =======================================================
      else if (cmd.equals("article write")) {
        System.out.println("== 게시글 작성 ==");
        int id = lastArticleId + 1;

        System.out.print("제목 : ");
        String title = sc.nextLine().trim();
        System.out.print("내용 : ");
        String body = sc.nextLine().trim();

        // 맨 밑에 만든 Util 클래스(도구상자)를 이용해 현재 시간을 쉽게 가져옵니다.
        // (★ 회원님의 날짜 구하는 자세한 주석은 맨 밑 Util 클래스 안으로 옮겼습니다!)
        String regDate = Util.getNowStr();
        String updateDate = Util.getNowStr(); // 처음엔 작성일과 수정일이 같습니다.

        Article article = new Article(id, regDate, updateDate, title, body);

        //설계도를  보고 진짜 실체를 만들어내는 과정이라고 해석한다.
        //new Article(...): Article이라는 설계도를 보고,
        //방금 위에서 입력받은 id, title, content 재료를 다 집어넣어서 새로운 진짜 게시글 1개를 만들어라 라는 뜻이다.
        // Article article =: 그렇게 만들어진 진짜 게시글(우변)에 article이라는 이름표를 붙여서 내가 컨트롤하겠다는 뜻이다.
        // (앞의 대문자 Article은 타입(설계도 종류)이고, 소문자 article은 제가 마음대로 지은 이름표이다.)

        articles.add(article);

        // articles는 맨 위에서 만든 게시글을 담아주는 리스트(상자)이다.
        // .add( ) 는 리스트가 제공하는 기능으로, 상자 안에 무언가를 집어넣으라는 뜻이다.
        // article 은 위  Article article = new Article(id, title, content); 여기서 이름표 붙인 진짜 게시글이다.

        System.out.printf("%d 번 게시글이 작성되었습니다.\n", id);
        // 형식을 저장해서 변수를 대입하려면 printf 를 사용해야 한다.
        // printf 는 자동 줄바꿈을 하지 않으므로 \n 을 붙이는게 좋다.

        lastArticleId++;

        //게시글 전용 번호표 기계'의 숫자를 1칸 올려두는 마무리 작업
      }

      // =======================================================
      // [3] 목록 보기 및 검색 (article list [검색어])
      // =======================================================
      else if (cmd.startsWith("article list")) {
        String searchKeyword = cmd.substring("article list".length()).trim();

        //cmd에 들어있는 전체 문장에서, 'article list'의 글자 수만큼 앞부분을 잘라내고,
        //남은 글자의 양끝 공백을 없앤 최종 결과물을 searchKeyword라는 문자열 변수에 저장하라는 뜻.
        //. (점) : 기능은 접근 연산자로 "앞에 있는 데이터가 가지고 있는 내장 기능(메서드)을 꺼내 쓰겠다"는 연결 고리이다.
        //substring(...) 은 문자열 절단 함수로 괄호 안에 들어간 숫자(인덱스) 위치부터 맨 끝까지를 잘라서 가져오는 기능이다.

        List<Article> forPrintArticles = articles;

//자바에서는 새로운 상자(변수)를 만들 때, "이 상자에 앞으로 뭘 담을 건지" 컴퓨터에게 무조건 미리 신고해야 하기 때문이다.
//List: 이 상자에는 데이터 하나가 아니라, 여러 개를 줄줄이 엮어서 담을 거다
//<Article>: "그리고 그 내용물은 '게시글'만 허용한다

        if (searchKeyword.length() > 0) {
          forPrintArticles = new ArrayList<>();

          //forPrintArticles: 처음엔 큰 통을 같이 쓰다가, 플라스틱만 골라내라는 명령(if)이 떨어지면
          // 새로운 빈 봉투(new ArrayList)를 꺼내는 겁니다. 그다음 큰 통에서 플라스틱을 발견할 때마다 그 새 봉투에만 담는 것이다.

          for (Article article : articles) {
            if (article.getTitle().contains(searchKeyword)) {

            //.contains : 괄호 안에 넣은 글자가 앞에 있는 문장에 들어있는지 없는지만 확인한다.
            // 결과로 (true) 아니면 (false)

              forPrintArticles.add(article);
            }
          }
        }

        System.out.println("== 게시물 목록 ==");
        if (forPrintArticles.isEmpty()) {

          //isEmpty() : 리스트 안에 내용 유무를 체크해서 '참/거짓'으로 답해주는 자바 전용 탐지기이다.
          //내용이 있다면 false 로 답하여서 if문을 벗어나 밑으로 내려간다.
          //내용이 없다면 거짓으로 true로 답하고 continue를 다시 (명령어 : ) 로 올라간다.

          System.out.println("시스템이 존재하지 않습니다.");
          continue;
        }

        System.out.println(" 번호  /  날짜  /  제목  /  내용  ");
        for (int i = forPrintArticles.size() - 1; i >= 0; i--) {
          // 최신 글부터 역순으로 보여주기 위한 장치이다.
          // 리스트를 0부터 센다.
          // int i = articles.size() - 1 은 총 개수에서 제일 끝자리부터 시작한다는 뜻이다.
          // -1은 저장공간이 3개이면 0부터 시작하여 2까지의 3칸이 마련되기에 최신것을 부르려면 -1을 해야 한다.
          // 줄여가며 하나씩 간다.
          //리스트에 있는 게시글을 뒤에서 부터 (최신순으로) 꺼낸다.

          Article article = forPrintArticles.get(i);
          //상자 리스트에서 i번째 게시글을 꺼내서 article 이라는 이름표를 붙여주는 과정이 출력문 바로 위에서 필요하다.
          //get(i)는 그 상자에서 i번째 칸에 있는 게시물 하나를 손으로 끄집어내는 것이다.
          //꺼낸 게시물에 article이라는 임시 이름표를 붙여준다.
          //이렇게 해야 바로 밑줄에서 article.getTitle()처럼 그 게시물에게 말을 걸 수 있기 때문이다.

          String today = Util.getNowStr().split(" ")[0];

// 오늘 날짜만.
// 손에 "2026-04-12 23:20:14" 라고 적힌 긴 종이 한 장이 있다.
// split(" ") 으로 띄어쓰기(" ")가 있는 곳을 가위로 싹둑 자른다. 이제 종이가 2장이 되었다.
// 앞장 : "2026-04-12" , 뒷장 : "23:20:14"
// [0] : 앞장 선택 .   컴퓨터는 숫자를 셀 때 1이 아니라 0부터 센다.
// 0번 종이 = 앞장 (2026-04-12),  1번 종이 = 뒷장 (23:20:14)
// 즉, [0]은 자른 종이 중에서 "0번째(앞장) 종이만 나한테 넘기라는 뜻이다.
// String today = : 서랍에 보관, 넘겨받은 0번째 종이(날짜)를 책상에 있는 today라는 이름표가 붙은 서랍에 집어넣으라는 뜻이다.

          String regDay = article.getRegDate().split(" ")[0];

//          게시물 작성 날짜만.

          if (today.equals(regDay)) {
            System.out.printf("  %d   /  %s  /  %s  /  %s  \n", article.getId(), article.getRegDate().split(" ")[1], article.getTitle(), article.getBody());
          } else {
            System.out.printf("  %d   /  %s  /  %s  /  %s  \n", article.getId(), regDay, article.getTitle(), article.getBody());
          }
          //어떤 article인지 컴퓨터가 몰라서 위의 코드를 입력해줘야 한다.
        }
      }

      // =======================================================
      // [4] 상세 보기 (article detail)
      // =======================================================
      else if (cmd.startsWith("article detail ")) {
        System.out.println("== 게시글 상세보기 ==");
        // 1. "article detail 1" 이라는 문장을 띄어쓰기 기준으로 쪼개서, 3번째 조각("1")을 진짜 숫자로 바꿉니다.
        String[] cmdBits = cmd.split(" ");

        //잘린 조각들이 cmdBits라는 칸막이 상자(배열)에 순서대로 담긴다.
        //[0]번 칸 : "article"
        //[1]번 칸 : "delete"
        //[2]번 칸 : "5" (우리가 필요한 글 번호)
        int id = Integer.parseInt(cmdBits[2]);
        //[2]번 칸 : "5" (우리가 필요한 글 번호)를 숫자로 변환.

        Article foundArticle = null; // 찾은 게시글을 담을 '임시 빈 상자'

        // 2. 리스트 상자를 처음부터 끝까지 샅샅이 뒤집니다.
        for (Article article : articles) {
          if (article.getId() == id) { // "너 번호가 내가 찾는 번호랑 똑같아?"
            foundArticle = article; // 찾았다면 임시 상자에 담고
            break; // 그만 찾고 나옵니다.
          }
        }

        // 3. 다 뒤졌는데도 임시 상자가 비었다면 = 없는 번호
        if (foundArticle == null) {
          System.out.printf("%d번 게시글은 없습니다\n", id);
        } else {
          // 상자에 글이 있다면 예쁘게 양식에 맞춰 꺼내 보여줍니다.
          System.out.println("번호 : " + foundArticle.getId());
          System.out.println("작성날짜 : " + foundArticle.getRegDate());
          System.out.println("수정날짜 : " + foundArticle.getUpdateDate());
          System.out.println("제목 : " + foundArticle.getTitle());
          System.out.println("내용 : " + foundArticle.getBody());
        }
      }

      // =======================================================
      // [5] 게시글 삭제 (article delete)
      // =======================================================
      else if (cmd.startsWith("article delete ")) {
        System.out.println("== 게시글 삭제 ==");

        //.equals() 글자 하나하나가 완전히 똑같아야 한다.
        //.startsWith() 지정한 문자열로 시작만 하면 된다.
        //이전 단계에서 사용했던 `article write`나 `article list`는 보통 그 자체로 명령이 끝나지만,
        //삭제나 상세 보기는 "어떤 글을 삭제할 것인가?"에 대한 정보가 필요하다.
        //사용자가 `article delete 1` 를 입력할 때,
        //프로그램 입장에서는 `1`이라는 숫자가 매번 바뀔 텐데, `equals`를 쓰면 모든 경우의 수를 다 적어야 한다.
        //그래서 앞부분이 `article delete `로 시작하는지만 확인하고 그 뒤에 붙는 숫자는 나중에 따로 쪼개서 읽자"라는 전략을 취하는 것이다.
        //`equals`: "이거랑 토씨 하나 안 틀리고 똑같나?" (고정된 명령어)
        //`startsWith`: "일단 시작은 이걸로 하나? 뒤에 추가적인게 있어도 괜찮다." (데이터가 포함된 명령어)

        String[] cmdBits = cmd.split(" ");
        int id = Integer.parseInt(cmdBits[2]);

        //`split(" ")`의 특성은 문장을 띄어쓰기로 자르는 순간, 몇 조각이 나올지 이미 확정되는 것이다. (예: "article delete 1" → 무조건 3조각).
        //결론은 조각의 개수가 변할 일이 없으므로, 굳이 무거운 `List`를 쓰기보다는 가볍고 빠른 배열을 사용하는 것이 컴퓨터 자원을 아끼는 방법이다.
        //1. `cmd` (원본 데이터): 사용자가 입력한 전체 문장입니다. (예: `"article delete 1"`)
        //2. `.split(" ")`:** 띄어쓰기(공백)를 기준으로 문장을 자른다.
        //3. `String[] cmdBits`: 잘려진 조각들을 `cmdBits`라는 이름의 배열 상자에 순서대로 담는다.
        //결과물: `cmdBits[0]` 에는 `"article"`, `cmdBits[1]` 에는 `"delete"`, `cmdBits[2]` 에는 `"1"` 이 들어갑니다.
        //이렇게 쪼개 놓으면, 나중에 "무슨 명령을 내렸는지(`delete`)", "몇 번 글인지(`1`)" 필요할 때마다 번호(인덱스)표를 보고 쏙쏙 뽑아 쓰기 편해진다.

        Article foundArticle = null;
        //결론은 찾은 위치(게시물)를 저장할 건데, 아직은 못 찾았으니까 비어있다(null)고 해두자 라는 뜻입니다.

        for (Article article : articles) {
          //보관함(List)에 있는 게시물들을 처음부터 끝까지 하나씩 꺼내서 확인해보는 과정
          if (article.getId() == id) {
            // article.getId(): 방금 사물함에서 막 꺼내서 내 손에 쥔 그 게시물의 실제 번호이다.
            // id: 사용자가 맨 처음에 입력했던 내가 찾고 있는 바로 그 번호이다.
            foundArticle = article;
            //찾았다는 표시를 남겨야 합니다
            break;
          }
        }

        if (foundArticle == null) {
          System.out.printf("%d번 게시글은 존재하지 않습니다.\n", id);
        } else {
          articles.remove(foundArticle);
          //제거하는 함수는 remove();이다.
          System.out.printf("%d번 게시글이 삭제되었습니다.\n", id);
        }
      }

      // =======================================================
      // [6] 게시글 수정 (article modify)
      // =======================================================
      else if (cmd.startsWith("article modify ")) {
        System.out.println("== 게시글 수정 ==");
        // 1. 명령어 쪼개서 숫자(ID) 뽑아내기
        String[] cmdBits = cmd.split(" ");
        int id = Integer.parseInt(cmdBits[2]);

        Article foundArticle = null;
        // 찾은 게시글을 담을 빈 공간
        // null = (초기 상태): 지금은 탐색을 시작하기 전이니까, 아무것도 없는 '빈손(null)' 상태이다.
        // 숫자에서는 "없다"를 표현할 때 0이나 -1을 썼지만,
        // 게시물(객체)처럼 덩치가 큰 데이터에서는 비었다는 것을 표현할 때 null 이라는 단어를 쓴다.

        // 2. 리스트를 뒤져서 해당 ID를 가진 게시글 찾기
        for (Article article : articles) {
          if (article.getId() == id) {
            foundArticle = article; // 찾았다면 빈 공간에 쏙!
            break; // 찾았으니 반복문 탈출
          }
        }

        // 3. 찾은 결과에 따라 다르게 처리하기
        if (foundArticle == null) {
          // 못 찾았을 때
          System.out.printf("%d번 게시글은 없습니다.\n", id);
        } else {
          // 찾았을 때 (수정 진행)
          // 3-1. 기존 내용 보여주기
          System.out.println("기존 title : " + foundArticle.getTitle());
          //자바에서 . (점, Dot)은 한국어로 "~의 안에 있는" 또는 **"~가 가지고 있는"**이라는 뜻이다.
          //foundArticle: 조금 전 for문을 돌려서 찾아낸 다음, 쥐고 있는 게시글 전체(바구니)'
          //foundArticle.getTitle()은 "내 손에 쥐고 있는 찾은 게시글(foundArticle)의 제목(title) 이라는 뜻이 된다.

          System.out.println("기존 body : " + foundArticle.getBody());

          // 3-2. 새로운 내용 입력받기
          System.out.print("새 제목 : ");
          String newTitle = sc.nextLine().trim();
          System.out.print("새 내용 : ");
          String newBody = sc.nextLine().trim();

          // 3-3. 기존 게시글의 데이터 덮어쓰기 (★수정의 핵심★)
          foundArticle.setTitle(newTitle);
          foundArticle.setBody(newBody);
          foundArticle.setUpdateDate(Util.getNowStr());

          System.out.printf("%d번 게시글이 수정되었습니다.\n", id);
        }
      }
      else {
        System.out.println("사용할 수 없는 명령어 입니다.");
      }
    }

    System.out.println("== 프로그램 종료 ==");
    sc.close();
  }
}

// ========================================================================
// 캡슐화가 적용된 Member(회원) 클래스
// ========================================================================
class Member {

//  신규 회원이 가입할 때, 그 사람의 정보를 담아둘 **'회원 전용 상자'**를 만드는 틀이다.

  private int id;
  private String regDate;
  private String updateDate;
  private String loginId;
  private String loginPw;
  private String name;

//  아이디, 비밀번호 같은 정보 앞에 private이 붙어 있다.
//  이건 외부에서 함부로 열어보고 조작하지 못하게 철통 보안(자물쇠)을 걸어라는 뜻이다. (이것을 '캡슐화'라고 부른다.)

  public Member(int id, String regDate, String updateDate, String loginId, String loginPw, String name) {
    //6개의 부품을 하나의 상자에 싹 쓸어 담고 16번 회원 홍길동 세트 완성하고 포장해 주는 역할이 바로 저 Member(...) 코드이다.
    this.id = id;
    this.regDate = regDate;
    this.updateDate = updateDate;
    this.loginId = loginId;
    this.loginPw = loginPw;
    this.name = name;
  }

  public int getId() { return id; }
  public String getLoginId() { return loginId; }
  public String getLoginPw() { return loginPw; }
  public String getName() { return name; }

//  getId(), getName() 등 (안내 데스크 - Getter): 상자를 자물쇠(private)로 잠가버려서,
//  나중에 회원 이름이 필요할 때 훔쳐볼 수가 없다.
//  그래서 "합법적으로 내용물을 물어볼 수 있는 정식 창구"를 뚫어놓은 것이다.

}

// ========================================================================
// 캡슐화가 적용된 Article(게시글) 클래스
// ========================================================================
class Article {
  private int id;
  private String regDate; // 실시간 날짜를 담아둘 공간
  private String updateDate;
  private String title;
  private String body;

  public Article(int id, String regDate, String updateDate, String title, String body) {
    this.id = id;
    //날짜를 담아줄 공간
    this.regDate = regDate; // 매개변수로 들어온 실시간 날짜를 내 공간에 저장
    this.updateDate = updateDate;
    this.title = title;
    this.body = body;

    //public은 메인 클래스에서도 자유롭게 쓸 수 있도록 허락해 주는 키워드이다.
    //생성자 Article( ) 은 객체가 만들어질 때 해야 할 초기 설정들을 해주느 공장 조립 라인이다.
    //객체가 만들어 질 때 id, title, content등을 다 채워 만들어지게 한다. = 빈 껍데기가 아닌 내용 있게 함
    // () 안에 있는 id와 클래스가 가진 (게시글에 저장될 공간) id의 이름이 동일하다.
    // 따라서 this를 붙이면 이 설계도로 만든 나 자신의 것이라는 뜻이 된다.
    // this.id = id;는 "내가 가진 id 공간(this.id)에,
    // 방금 외부에서 입력받은 id 값(id)을 집어넣어라!"라는 명확한 지시어이다.
  }

  public int getId() { return id; }
  public void setId(int id) { this.id = id; }

  public String getRegDate() { return regDate; }
  public void setRegDate(String regDate) { this.regDate = regDate; }

  public String getUpdateDate() { return updateDate; }
  public void setUpdateDate(String updateDate) { this.updateDate = updateDate; }

  public String getTitle() { return title; }
  public void setTitle(String title) { this.title = title; }

  public String getBody() { return body; }
  public void setBody(String body) { this.body = body; }

  //set는 반환하지 않아도 되므로 void를 쓰고 get은 반환해야 하므로 return 을 쓴다.
  //괄호 안의 String body가 새 서류이다.
  //이 새 서류를 들고 창고로 가서, 기존 내용을 파기하고 새것으로 교체(=)한다.


//  회원의 아이디나 고유번호는 한 번 가입하면 바뀔 일이 거의 없지만,
//  게시글은 나중에 '수정(modify)'을 엄청나게 많이 하기 때문에 setter을 사용함.
//  역할: 기존에 있던 제목을 버리고, 내가 새로 가져온 제목으로 내용물을 갈아 끼우라고
//  지시하는 **'수정 전용 합법 창구(Setter)입니다.

}

// ========================================================================
// 시간을 예쁘게 포장해주는 도구상자 (Util)
// ========================================================================
class Util {
  public static String getNowStr() {
    // 이 두 줄이 무조건 있어야 regDate(실시간 시간)가 탄생한다!
    LocalDateTime now = LocalDateTime.now();
    // LocalDateTime (로컬데이트타임): 자바가 가지고 있는 **'디지털 시계'**의 이름(타입)입니다.
    // Date(날짜)와 Time(시간)을 같이 가지고 있다는 뜻이죠.
    // now: 우리가 만든 변수(상자) 이름입니다. '지금'이라는 뜻으로 제 마음대로 지은 겁니다.
    // LocalDateTime.now(): 자바의 시계에게 **"지금 당장(now) 시간을 딱 캡처해!"**라고 명령하는 기능입니다.
    // 결과: 컴퓨터는 아주 복잡하고 정밀한 시간을 now라는 상자에 담아둡니다.

    String regDate = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    // String regDate =: 변환된 예쁜 글자(String)를 담을 regDate(등록일)라는 빈 상자를 만듭니다.
    // now.format(...): 아까 위에서 시계 보고 캡처해 둔 now 시간에게
    // "괄호 안에 있는 양식(format)대로  모습을 좀 바꾸라고 시키는것.
    // DateTimeFormatter.ofPattern(...): 어떤 양식으로 바꿀지를 정해주는 도구이다.
    // "yyyy-MM-dd HH:mm:ss": 대망의 양식이다. 알파벳마다 뜻이 다 정해져 있다.

    return regDate;
  }
}
profile
성심당마스코트

0개의 댓글