본문 바로가기

개발기술/설계|디자인패턴

Java programming OOP 연습케이스(1)

리팩터링을 통해서 객체지향적 사고관을 기르는 연습을 해보자.

import org.w3c.dom.ls.LSOutput;
import java.time.LocalDate;
import java.time.DayOfWeek;
import java.lang.reflect.Array;
import java.util.Scanner;

public class Calendar {
    
    
    
    public static void main(String[] args) {
        // receive user input and set default value
        Scanner input = new Scanner(System.in);
        System.out.println("달력의 년도를 입력해 주세요. (yyyy)");
        int year = input.nextInt();
        input.nextLine();

        System.out.println("달력의 월을 입력해 주세요. (mm)");
        int month = input.nextInt();
        input.nextLine();

        // get length of month
        LocalDate date = LocalDate.of(year, month, 1);
        int endOfMonth = date.lengthOfMonth();

        // get int value of day of first date of month and adjust default value for formatting
        DayOfWeek dayOfWeek = date.getDayOfWeek();
        int midStartDefault = dayOfWeek.getValue()*(-1);

        System.out.println(dayOfWeek.getValue());
        System.out.println(midStartDefault);



        int k = midStartDefault;

        for (int i = 0; i < 2; i++) {
            System.out.print("일   월   화  수  목   금   토");
            System.out.print("           ");
        }
        System.out.println();
        // only print number when d is in range 7times considering start and end of the month

        for (int j = 0; j < 5; ++j) {
            for (int i = 0; i < 7; ++i) {
                midStartDefault++;
                if (midStartDefault > endOfMonth || midStartDefault < 1) {
                    System.out.print("    ");
                } else {
                    System.out.printf("%02d  ", midStartDefault);
                }

            }
            // sperate different calendar with spacing and repeat the loop
            System.out.print("         ");
            for (int i = 0; i < 7; ++i) {
                k++;
                if (k > endOfMonth || k < 1) {
                    System.out.print("    ");
                } else {
                    System.out.printf("%02d  ", k);
                }


            }
            System.out.println();
        }
    }

}

 

위 코드는 사용자로부터 입력값을 받고, 그 입력값을 외부 패키지 로직을 통해 가공한 뒤, 3개의 달력모형을 출력하는 구조로 이루어져 있다.

리팩토링을 고려할 수 있는 요소는 아래와 같다.

 

1. Construct를 활용해서 입력값 및 변수정의를 별도로 분리한다

- 개선점 1. 중요한 변수를 따로 분리함으로 가독성을 올림 (분류) 2. 변수가 전체범위로 선언됨에 따라 메소드를 추가가능(확장성)

 

2. 입력값을 가공하는 부분은 메소드로 따로 분리함

- 개선점 코드 반복사용을 줄여서 가독성을 올림 (분류)

두개의 return 값을 반환해야하는 method라서 차라리 class를 새로 생성하는게 나아보였지만 과제 특성상 class하나만 생성필요해서 array return method로 대체

 

3. 반복되는 print 부문 메소드로 따로 분리함

- 개선점 코드 반복사용을 줄여서 가독성을 올림 (분류)

우선 코드를 작성해놓고 인텔리제 extract method 기능을 적극 활용할 것.

 

리팩터 후 코드

 

//변상화 제로베이스 미니과제5, mini-assgn-bsh05.java

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.Scanner;

public class Calendar {
    int year;
    int month;


    public Calendar() {
        // receive user input
        Scanner input = new Scanner(System.in);
        boolean valid = true;
        while (valid) {
            try {
                System.out.print("달력의 년도를 입력해 주세요. (yyyy)");
                year = input.nextInt();
                input.nextLine();

                if (0 <= year && year <= 9999) { // check if the value is valid
                    valid = false;
                } else {
                    System.out.println("유효하지 않은 입력값입니다.");
                }
            } catch (Exception e) {
                System.out.println("유효하지 않은 입력값입니다.");
                input.nextLine();
            }
        }

        valid = true;
        while (valid) {
            try {
                System.out.print("달력의 월을 입력해 주세요. (mm)");
                month = input.nextInt();
                input.nextLine();

                if (2 <= month && month <= 11) { // check if the value is valid
                    valid = false;
                } else {
                    System.out.println("유효하지 않은 입력값입니다.");
                }
            } catch (Exception e) {
                System.out.println("유효하지 않은 입력값입니다.");
                input.nextLine();
            }
        }
    }

    public static void main(String[] args) {
        Calendar calendar = new Calendar();

        // get int value from whateverday of first date of month, adjust int value for pringting
        // [0] : start of the month and adjust value for day of week, [1] end of the month

        int[] thisMonth = dayValDefaultSetting(calendar.year, calendar.month);
        int[] nextMonth = dayValDefaultSetting(calendar.year, calendar.month + 1);
        int[] lastMonth = dayValDefaultSetting(calendar.year, calendar.month - 1);


        for (int i = 0; i < 3; i++) {
            System.out.printf("[%d년 %02d월]", calendar.year, (calendar.month - 1 + i));
            System.out.print("                         ");
        }
        System.out.println();

        for (int i = 0; i < 3; i++) {
            System.out.print("일   월   화  수  목   금   토");
            System.out.print("           ");
        }
        System.out.println();


        for (int j = 0; j < 5; ++j) {
            // sperate different calendar with spacing and repeat the loop
            printCalendar(lastMonth);
            System.out.print("         ");

            printCalendar(thisMonth);
            System.out.print("         ");

            printCalendar(nextMonth);
            System.out.println();
        }
    }

    private static void printCalendar(int[] lastMonth) {
        // only print number when arry[0] is in range at 7times
        for (int i = 0; i < 7; ++i) {
            lastMonth[0]++;
            if (lastMonth[0] > lastMonth[1] || lastMonth[0] < 1) {
                System.out.print("    ");
            } else {
                System.out.printf("%02d  ", lastMonth[0]);
            }

        }
    }

    private static int[] dayValDefaultSetting(int year, int month) {
        // get int value from whateverday of first date of month, adjust int value for pringting
        int[] arry = new int[2];
        LocalDate date = LocalDate.of(year, month, 1);
        arry[1] = date.lengthOfMonth();

        DayOfWeek dayOfWeek = date.getDayOfWeek();
        arry[0] = dayOfWeek.getValue() * (-1);
        return arry;
    }

}

'개발기술 > 설계|디자인패턴' 카테고리의 다른 글

클래스 다이어그램  (1) 2024.09.10
프로젝트 설계 및 문서화  (0) 2024.08.14
디자인패턴  (0) 2024.08.10
성능 최적화 전략  (0) 2024.08.02
Spring 도입배경 - 객체지향 디자인원리  (1) 2024.05.06