로직, 매서드의 간소화

Kim DongKyun·2022년 11월 28일
0

Weekly I Learned

목록 보기
2/8

<1> 로직, 매서드의 간소화

A class should have one, and only one reason to change. - Robert C Martin

🌟 하나의 클래스는 단 하나의 책임을 가져야 하고, 하나의 책임의 기준은 “변경”이다. 변경이 일어날 때의 비용이 적어야 한다. - 김승민 튜터님

은행 관리 프로젝트에서 각자 분업해서 로직을 만들던 중, 우리의 코드에 겹치는 부분이 있음을 확인했다.

아래 매서드는
은행 사용자의 아이디, 이름, 계좌 정보를 출력해주는 매서드(그림1)
은행 사용자가 예금한 금액을 출금하게 해주는 매서드(그림2)


  • 위 두 매서드는 공통으로 accountlist에서 고객의 계좌 정보를 받아오는 for문을 사용한다.
  • 위와 같이 코드를 작성 했을 때 문제는 다음과 같다.
  1. 매서드에서 매번 로직을 다시 짜야한다.
  2. 매서드마다 로직을 수행하는 방식, 예외 처리등이 다를 경우에 문제가 발생할 확률이 높다.

이 공통된 로직들을 정리한다면?

  • 계좌 번호, 계좌 잔액, 사용자명 등등을 모두 출력해주는 showAccountInfo를 만들어서 로직을 간소화하고 오류를 최소화 가능하다.
  • 즉, 변경 비용의 최소화가 가능하고(1), 간결한 코드로 재탄생하게 된다.

<2> 오류가 일어난 이유와 그 해결

🌟 *협업을 통해 동시 다발적으로 한 페이지의 매서드를 작성하게 될 때, 오류 사항에 대해서 반드시 다시 점검해야 한다. 우리는 계속 **구동 상황을 테스트 하면서 여러 문제를 해결해냈다.***

<문제 상황>

우리는 사용자의 계좌를 모두 출력받은 후 삭제를 원하는 계좌를 선택할 수 있는 로직을 구현하기를 원했다.

  • 1번 코드(향상 for문을 사용한 모습)

위와 같이 작성했다. 이 코드는 잘 실행될까?

  • 1번 코드의 문제는 다음과 같다.

    • 위에서 볼 수 있듯, 계좌 ”번호” 를 받을 수 없을 뿐더러(계좌의 위치를 알려주기만 함), idx값이 1 선언되었고 변하지 않기 때문에 1,2,3 … 와 같이 계좌의 인덱스를 표현해 줄 수 없었다.
  • 2번 코드 ( int i~ 형식의 for문을 사용한 모습-fori)

    • 이 코드는 어떨까?
    • idx값이 1씩 늘어나서 계좌의 인덱스를 표현 해 줄 수 있다.
    • 그렇다면 이 코드가 최선일까? 우리의 완성 코드는 다음과 같다.
private void deleteAccount() {
clearCmd();
println(BLANK+HEADER_DELETE_ACCOUNT);
    findAllUserID();
print(BLANK+ENTER_USER_ID_ACCOUNT);
    String userId = scanAndGetString();
    List<Account> userAccounts;
    try {
        userAccounts = adminLogic.getUserAccountsByID(userId);
    } catch (Exception e) {
        setMessage(MESSAGE_NO_ACCOUNT);
        return;
    }
println(BLANK+ userId +IS_ACCOUNT_LIST);
    for (int i = 0; i < userAccounts.size(); i++) {
println(BLANK+ (i + 1) + ". " + userAccounts.get(i).getAccountNum());
    }
print(BLANK+ENTER_ACCOUNT);
    int idx = scanAndGetParsedInt();
    Account account;
    try {
        account = userAccounts.get(idx - 1);
    } catch (Exception e) {
        setMessage(MESSAGE_WRONG_INPUT);
        return;
    }
    if(idx == -1) {
        setMessage(MESSAGE_WRONG_INPUT);
        return;
    }
print(BLANK+ENTER_Y_TO_DELETE);
    if (scanner.nextLine().equals("y")) {
        adminLogic.deleteAccount(account);
        setMessage(MESSAGE_SUCCESS_LOGIC);
    } else {
        setMessage(MESSAGE_STOP_LOGIC);
    }
}
  • 이 코드는 여러 상황과 예외에 대한 처리가 모두 달려있다. 하나하나 뜯어보자.
  1. 헤더를 보여주고, findAllUserID를 실행해서 모든 유저의 아이디를 보여준 후, 유저의 입력값을 받는다.

  1. 입력받은 userId 가 AccountList인 userAccounts에 있는지 확인한다. 없으면 에러 메시지를 출력한다.

  1. 입력받은 아이디의 계좌를 모두 조회한다.

  1. 계좌의 인덱스를 scanAndGetParsedInt() 매서드를 이용해 입력받고, 이 값을 idx로 선언한 뒤 유저가 입력한 값이 있으면 특정 account를 리턴하고, 아니라면 에러 메시지를 송출한다.

  2. 마지막으로 유저가 “y”를 입력했을 시 삭제할 수 있도록 안전장치를 만들었다. 유저가 y를 입력하면 deleteAccount(account) 매서드를 실행하고, 아니라면 에러 메시지를 송출한다.


    <3> 결론

    우리는 위와 같이 여러 케이스를 실험해보고, 트러블 슈팅을 진행했다. 트러블 슈팅의 진행 상황 동안 우리는

    첫째 : 코드를 간소화, 중복된 로직의 매서드화를 진행했다.

    둘째 : 오류가 나는 코드를 테스트 해 보고 우리가 원래 계획했던 방식으로 작동하도록 만들었다.

    셋째 : 사용자의 편의를 위해 여러 예외 사항을 추가하고, 프로그램의 에러를 최소화했다.

🌟 즉, 동료들이 코드를 보다 쉽게 이해하고! 사용 상황에서 편의성을 극대화 했다.


<4> 이번 한주의 회고

이번 한 주는 프로젝트를 수행하느라 아주 바빴다. 다른 생각 할 필요 없이 프로젝트에서 요구하는 사항들을 구현하기 위해 100% 몰입했다고 생각한다. 아주 만족스러운 한 주였고, 다음 주도 이렇게 진행할 것이다.

1개의 댓글

comment-user-thumbnail
2022년 11월 28일

회고록을 보니 정말 한주간 몰입 제대로 하신 게 여실히 느껴지네요!! 그 기운을 쭉쭉 이어가시길 바랍니다: )

답글 달기