The Debugging Chronicles : "코드의 미학"

함수 제작하기 본문

JAVA/자바 수업 내용

함수 제작하기

sweetseonah1004 2024. 7. 1. 11:47

아래 학생부 출력하는 코드로 함수 제작하는 방법에 대해서 생각해 보려고 한다.

 

1. 코드 먼저 작성하고 >> 함수화
2. 함수 먼저 작성하고 >> main ()에 적용

 

package class02;

import java.util.Scanner;

public class Test01 {

   public static void main(String[] args) {
      String[] datas = new String[5];
      Scanner sc=new Scanner(System.in);
      System.out.println("학생부 프로그램");

      datas[0]="티모";
      datas[1]="아리";
      datas[2]="모르가나";
      int cnt=3; 

      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. 프로그램 종료");
         System.out.println("===============");
         System.out.print("메뉴 입력 >> ");
         int menu=sc.nextInt();

         if(menu==0) {
            System.out.println("프로그램이 종료됩니다.");
            break;
         }
         
         else if(menu==1) { // 학생추가

            if(cnt >= datas.length) {
               System.out.println("더이상 데이터를 저장할수없습니다!");
               continue;
            }

            String name;
            while(true) {
               System.out.print("저장하고싶은 학생의 이름을 입력해주세요. >> ");
               name=sc.next();

               System.out.print("정말 "+name+"(으)로 하시겠습니까? (Y/N) >> ");
               String answer=sc.next();

               if(answer.equals("Y")) {

                  boolean flag=false;

                  for(int i=0;i<cnt;i++) {
                     if(name.equals(datas[i])) {
                        flag=true;
                        System.out.println(name+"은(는) 이미 존재하는 이름입니다...");
                     }
                  }
                  if(!flag) {
                     break;
                  }

               }
            }
            datas[cnt]=name;
            cnt++;

            System.out.println(name+"이(가) 저장되었습니다!");

         }
         else if(menu==2) { // 학생부 전체출력

            if(cnt<=0) { 
               System.out.println("보여줄 학생 데이터가 없습니다.");
               continue;
            }


            System.out.println("=== 학생 목록 ===");
            for(int i=0;i<cnt;i++) { 
               System.out.println((i+1)+"번 학생 : "+datas[i]);
            }
            System.out.println("===============");
         }
         else if(menu==3) { // 이름으로 검색
            System.out.print("검색어 입력 >> ");
            String searchContent=sc.next(); // searchKeyword

            boolean flag=false; // 검색결과가 없는 상태로 시작

            System.out.println("===============");
            for(int i=0;i<cnt;i++) {
               if(datas[i].contains(searchContent)) { // 티모안에 모가 있니?
                  System.out.println(datas[i]);
                  flag=true; // 검색결과를 찾은 상태
               }
            }
            
            if(!flag) { // 검색결과가 없다면
               System.out.println("검색결과가 없습니다...");
            }
            
            System.out.println("===============");


         }
         else if(menu==4) { // 번호로 검색 => PK로 검색 == selectOne(getOne)

            if(cnt<=0) { // 학생이 한명도 저장되어있지않다면
               System.out.println("검색할 학생 데이터가 없습니다!");
               continue; // 프로그램 처음으로 돌아가기
            }

            int num;
            while(true) {
               System.out.print("검색할 학생의 번호 입력 >> ");
               num=sc.nextInt();
               if(1<=num && num<=cnt) { // 경계값 검사
                  break;
               }
               System.out.println("올바른 번호를 입력해주세요!~~");
            }


            System.out.println(num+"번 학생의 이름은 "+datas[num-1]+" 입니다.");
         }
         else if(menu==5) { // 이름변경
            if(cnt<=0) {
               System.out.println("변경할 학생 데이터가 없습니다!");
               continue;
            }

            int num;
            while(true) {
               System.out.print("변경할 학생의 번호 입력 >> ");
               num=sc.nextInt();
               if(1<=num && num<=cnt) {
                  break;
               }
               System.out.println("올바른 번호를 입력해주세요!~~");
            }

            System.out.println(num+"번 학생의 이름은 "+datas[num-1]+" 입니다.");

            String name;
            while(true) {
               System.out.print("변경할 이름을 입력해주세요. >> ");
               name=sc.next();

               System.out.print("정말 "+name+"(으)로 하시겠습니까? (Y/N) >> ");
               String answer=sc.next();

               if(answer.equals("Y")) {

                  boolean flag=false;

                  for(int i=0;i<cnt;i++) {
                     if(name.equals(datas[i])) {
                        flag=true;
                        System.out.println(name+"은(는) 이미 존재하는 이름입니다...");
                     }
                  }


                  if(!flag) {
                     break;
                  }

               }
            }

            datas[num-1]=name;
         }
         else {
            System.out.println("제대로 입력해주세요~~");
         }
      }


   }

}

1. 이미 존재하는 코드를 함수화 시키는 방법

1.1 데이터 샘플링하기

    datas[0]="티모";
    datas[1]="아리";
    datas[2]="모르가나";
    int cnt=3;

 

   public static int sample(String[] datas) {
      // 학생부 배열에 샘플 데이터를 저장해주고,
      // 몇명이 저장되었는지 반환해주는 함수
      datas[0]="티모";
      datas[1]="아리";
      datas[2]="모르가나"; // 배열은 call by reference ▶ 반환 x
      int cnt=3; // 원시타입 ▶ 반환 o
      return cnt;
   }

 

>> 메인에 함수 출력하기

int cnt=sample(datas);

 

 

1.2 메뉴 출력부분 함수로 만들기

 

 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. 프로그램 종료");
 System.out.println("===============");
 System.out.print("메뉴 입력 >> ");
 int menu=sc.nextInt();
   public static int printMenu() {
      // 메뉴를 출력해주고,
      // 사용자로부터 메뉴번호로 입력받은 값을 반환해주는 함수
      Scanner sc=new Scanner(System.in);
      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. 프로그램 종료");
      System.out.println("===============");
      System.out.print("메뉴 입력 >> ");
      int menu=sc.nextInt();
      return menu;
   }

 

>> 메인에 함수 출력하기

int menu=printMenu();

 

1.3 반복되는 부분 함수로 만들기 -  더 이상 학생 데이터를 저장할 수 없을때

if(cnt >= datas.length) {
   System.out.println("더이상 데이터를 저장할수없습니다!");
   continue;
}

 

>> 생각해보기

 안에 continue 가 있다. 따라서 값이 반환될 때 true, false로 할 필요가 있다.

public static boolean isFull(int cnt,String[] datas) {
      // 더 이상 학생 데이터를 저장할 수 없을때
      if(cnt >= datas.length) {
         System.out.println("더이상 데이터를 저장할수없습니다!");
         return true;
      }
      return false;
 }

 

>> 생각해보기 

코드에 제어문이 존재할 때

   >>제어문은 main()에 위치해야만함!

   >>if문과 함께 사용될  가능성이 매우 높음

   >>isXxx(), hasXxx() 같은 boolean 반환 메서드로 변환

 

>> 메인에 함수 출력하기

if(isFull(cnt,datas)) {
      continue;
}

 

 

1.4 서로 비슷한 기능인데, 완벽히 동일하지 않을 때 - 아직 저장된 학생 데이터가 전혀 없을때

// else if(menu==1) 

String name;
while(true) {
   System.out.print("저장하고싶은 학생의 이름을 입력해주세요. >> ");
   name=sc.next();

   System.out.print("정말 "+name+"(으)로 하시겠습니까? (Y/N) >> ");
   String answer=sc.next();

   if(answer.equals("Y")) {
      boolean flag=false;
      for(int i=0;i<cnt;i++) {
         if(name.equals(datas[i])) {
            flag=true;
            System.out.println(name+"은(는) 이미 존재하는 이름입니다...");
         }
      }

      if(!flag) {
         break;
      }
   }
}

datas[cnt]=name;
cnt++;
//else if(menu==5)

String name;
while(true) {
   System.out.print("변경할 이름을 입력해주세요. >> ");
   name=sc.next();

   System.out.print("정말 "+name+"(으)로 하시겠습니까? (Y/N) >> ");
   String answer=sc.next();

   if(answer.equals("Y")) {
      boolean flag=false;
      for(int i=0;i<cnt;i++) {
         if(name.equals(datas[i])) {
            flag=true;
            System.out.println(name+"은(는) 이미 존재하는 이름입니다...");
         }
      }
      if(!flag) {
         break;
      }
   }
}

datas[num-1]=name;

 

>> 생각해보기

 *   1. 함수를 호출하고, 내부에서 1/2 버튼식으로 조정

 *   2. 같은 부분까지만 함수로 두고, 다른 부분은 함수화 x

 

   public static String inputName(int cnt,String[] datas) {
      // 사용자가 이름을 입력하면 그 이름 값을 반환하는 함수
      Scanner sc=new Scanner(System.in);
      String name;
      while(true) {
         System.out.print("변경할 이름을 입력해주세요. >> ");
         name=sc.next();

         System.out.print("정말 "+name+"(으)로 하시겠습니까? (Y/N) >> ");
         String answer=sc.next();

         if(answer.equals("Y")) {

            boolean flag=false;

            for(int i=0;i<cnt;i++) {
               if(name.equals(datas[i])) {
                  flag=true;
                  System.out.println(name+"은(는) 이미 존재하는 이름입니다...");
               }
            }

            if(!flag) {
               break;
            }

         }
      }
      return name;

   }

 

>> 메인에 함수 출력하기

String name=inputName(cnt, datas);
datas[cnt]=name;
cnt++;
datas[num-1]=inputName(cnt, datas);

 

2. 아무것도 없을 , 함수 부터 제작하는 방법

 

2.1 학생부 전체 출력 담당하는 기능의 함수

 

   // input, output 먼저 생각해보기!!!!!!!!!!

   // input : 학생부 데이터, 현재 저장된 학생의 수

   // output : x

   public static void printStudents(String[] datas,int cnt) {
      System.out.println("=== 학생 목록 ===");
      for(int i=0;i<cnt;i++) {
         System.out.println((i+1)+"번 학생 "+datas[i]);
      }
      System.out.println("====================");
   }

>> 생각해보기

 1. input, output을 고려해보고

 2. 그에 맞는 메서드 시그니쳐 선언(정의)

 3. 기능 구현

 4.변경사항 적용하기

 

>> 메인에 함수 출력하기

printStudents(datas,cnt);

 

 

2.2 학생 번호로 검색

   // input : 학생부 데이터, 현재 저장된 학생의 수

   // output : x (대체적으로 출력(select,read,R)기능은 output이 없음)

  public static boolean isRight(int num,int cnt) {
      if(1<=num && num<=cnt) {
         return true;
      }
      return false;
  }
  
  public static int selectOne(String[] datas,int cnt) {
      Scanner sc=new Scanner(System.in);
      int num;
      while(true) {
         System.out.print("검색할 번호 입력 >> ");
         num=sc.nextInt();
         if(isRight(num,cnt)) {
            break;
         }
      }      
      System.out.println(num+"번 학생은 "+datas[num-1]+"입니다.");
      return num;
   }

 

 

>> 메인에 함수 출력하기

 int num=selectOne(datas,cnt);

 

 

3.완선된 코드

package class02;

import java.util.Scanner;

public class Test01 {

   public static int sample(String[] datas) {
      // 학생부 배열에 샘플 데이터를 저장해주고,
      // 몇명이 저장되었는지 반환해주는 함수
      datas[0]="티모";
      datas[1]="아리";
      datas[2]="모르가나"; // 배열은 call by reference ▶ 반환 x
      int cnt=3; // 원시타입 ▶ 반환 o
      return cnt;
   }

   public static int printMenu() {
      // 메뉴를 출력해주고,
      // 사용자로부터 메뉴번호로 입력받은 값을 반환해주는 함수
      Scanner sc=new Scanner(System.in);
      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. 프로그램 종료");
      System.out.println("===============");
      System.out.print("메뉴 입력 >> ");
      int menu=sc.nextInt();
      return menu;
   }

   public static boolean isFull(int cnt,String[] datas) {
      // 더 이상 학생 데이터를 저장할 수 없을때
      if(cnt >= datas.length) {
         System.out.println("더이상 데이터를 저장할수없습니다!");
         return true;
      }
      return false;
   }
   public static boolean isEmpty(int cnt) {
      // 아직 저장된 학생 데이터가 전혀 없을때
      if(cnt<=0) { 
         System.out.println("저장된 학생 데이터가 없습니다.");
         return true;
      }
      return false;
   }

   public static String inputName(int cnt,String[] datas) {
      // 사용자가 이름을 입력하면 그 이름 값을 반환하는 함수
      Scanner sc=new Scanner(System.in);
      String name;
      while(true) {
         System.out.print("변경할 이름을 입력해주세요. >> ");
         name=sc.next();

         System.out.print("정말 "+name+"(으)로 하시겠습니까? (Y/N) >> ");
         String answer=sc.next();

         if(answer.equals("Y")) {

            boolean flag=false;

            for(int i=0;i<cnt;i++) {
               if(name.equals(datas[i])) {
                  flag=true;
                  System.out.println(name+"은(는) 이미 존재하는 이름입니다...");
               }
            }


            if(!flag) {
               break;
            }

         }
      }
      return name;

   }

   // 학생부 전체 출력 담당하는 기능의 함수
   // input, output 먼저 생각해보기!!!!!!!!!!
   // input : 학생부 데이터, 현재 저장된 학생의 수
   // output : x
   public static void printStudents(String[] datas,int cnt) {
      System.out.println("=== 학생 목록 ===");
      for(int i=0;i<cnt;i++) {
         System.out.println((i+1)+"번 학생 "+datas[i]);
      }
      System.out.println("====================");
   }

   public static boolean isRight(int num,int cnt) {
      if(1<=num && num<=cnt) {
         return true;
      }
      return false;
   }

   // 학생 번호로 검색
   // input : 학생부 데이터, 현재 저장된 학생의 수
   // output : x (대체적으로 출력(select,read,R)기능은 output이 없음)
   public static int selectOne(String[] datas,int cnt) {
      Scanner sc=new Scanner(System.in);
      int num;
      while(true) {
         System.out.print("검색할 번호 입력 >> ");
         num=sc.nextInt();
         if(isRight(num,cnt)) {
            break;
         }
      }      
      System.out.println(num+"번 학생은 "+datas[num-1]+"입니다.");
      return num;
   }


   public static void main(String[] args) {
      String[] datas = new String[5];
      Scanner sc=new Scanner(System.in);
      System.out.println("학생부 프로그램");

      int cnt=sample(datas);

      while(true) {
         int menu=printMenu();
         if(menu==0) {
            System.out.println("프로그램이 종료됩니다.");
            break;
         }
         else if(menu==1) { // 학생추가

            /*
            if(cnt >= datas.length) {
               System.out.println("더이상 데이터를 저장할수없습니다!");
               continue;
            }
             */
            if(isFull(cnt,datas)) {
               continue;
            }



            String name=inputName(cnt, datas);
            datas[cnt]=name;
            cnt++;

            System.out.println(name+"이(가) 저장되었습니다!");

         }
         else if(menu==2) { // 학생부 전체출력

            /*
            if(cnt<=0) { 
               System.out.println("보여줄 학생 데이터가 없습니다.");
               continue;
            }
             */
            if(isEmpty(cnt)) { 
               continue;
            }

            printStudents(datas,cnt);
         }
         else if(menu==3) { // 이름으로 검색

            // 검색어를 입력 >> 
            // 이 검색어가 맞습니까? xxx : 사용자가 하는 입력이 데이터에 변화를주지않기때문
            System.out.print("검색어 입력 >> ");
            String searchContent=sc.next(); // searchKeyword

            boolean flag=false; // 검색결과가 없는 상태로 시작

            // 학생부를 하나하나 확인하면서
            System.out.println("===============");
            for(int i=0;i<cnt;i++) {
               // 학생의 이름안에 검색어가 있니? ==> 티모 == 모 xxxxx 티모안에 모가 있니? o
               if(datas[i].contains(searchContent)) { // 티모안에 모가 있니?
                  System.out.println(datas[i]);
                  flag=true; // 검색결과를 찾은 상태
               }
               // 있다면, 출력
               // 없다면, 출력 x
            }

            if(!flag) { // 검색결과가 없다면
               System.out.println("검색결과가 없습니다...");
            }
            // 검색결과가 없다면, 없다고 알려주기
            // 1. 검색결과가 없다는 출력은 한번만! 수행하기때문에 반복문 바깥에있어야함
            // 2. 검색결과가 없다는 사실은 검색을 다~~~ 해봐야알수있음
            // ===>> flag 로직 대표적인 케이스 !!!

            System.out.println("===============");


         }
         else if(menu==4) { // 번호로 검색 => PK로 검색 == selectOne(getOne)
            // Primary Key : "데이터를 '식별'"할 수 있게 해주는 값
            // ex) 주민번호, 학번, ...
            // 사용자가 지정하는 것이 아니라, 프로그램에서 부여하는 값
            // 현재 학생부 프로그램에서는 '번호' == PK

            if(isEmpty(cnt)) { 
               continue;
            }

            selectOne(datas,cnt);

         }
         else if(menu==5) { // 이름변경

            // UPDATE : UPDATE 처리할 대상 데이터가 특정되어있어야함!
            // ex) 프로필 사진 변경, 닉네임 변경, ...

            // 이름을 변경할 학생의 번호 입력 >>
            // PK로 데이터를 특정한 후에 UPDATE를 진행해야함


            if(isEmpty(cnt)) { 
               continue;
            }


            int num=selectOne(datas,cnt);



            datas[num-1]=inputName(cnt, datas);
         }
         else { // 유효성 검사
            System.out.println("제대로 입력해주세요~~");
         }
      }


   }

}