Java

토이프로젝트 후 느낀점

인생은단짠단짠 2022. 10. 29. 20:25

 

프로젝트 주제

 

스마트스토어 운영진을 위한 고객 분류 프로그램 개발 개별 프로젝트 👤

 

  • 유의사항
    • 해당 프로젝트는 클래스 및 메소드 설계를 직접 해보는 것이 목적이므로 List, Set, Map과 같은 API의 사용은 금합니다.
    • List, Set, Map의 내부를 분석해보고 이와 비슷하게 직접 함수를 작성해보세요.
  • 고객 분류 결과
    • General
    • VIP
    • VVIP
  • 고객 분류기준
    • 분류기준은 무조건 총 이용시간과 결제금액으로 정의하고 각 그룹이 되기 위한 최소 이용시간과 결제금액은 해당 프로그램을 사용하는 운영진에게 입력받는 형태입니다.

 

 

 

 

받은 피드백

 

Git Commit

커밋의 단위는 최대한 잘게 쪼개는 것이 좋습니다.

커밋의 단위를 나눠서 해주신 부분 매우 좋습니다!!조금더 욕심을 부려보자면 더 잘게 쪼갤 수 있을 것 같습니다.


코드 스타일

코드를 커밋하기전에는 항상 인텔리제이의 자동정렬 기능을 사용해 불필요한 코드들을 제거하는 습관을 들이면 좋습니다.또한, 사용하지 않는 변수, 주석, 메서드는 과감히 삭제해주세요!


리플렉션

구현을 하면서 리플렉션을 사용하셨는데요. 리플렉션의 사용은 최대한 지양하는 것이 좋습니다.리플렉션은 프레임워크를 만들 때 유저의 실제 코드를 모르기 때문에 주로 사용되는 기능인데요.리플렉션은 성능상에 이슈가 있고 각 메서드들이 어떤 시점에 어디서 호출되는지 파악하기 어렵습니다.즉, 런타임 시점이 되어야만 알 수 있는 거죠.(캡슐화를 파괴합니다.)추가적으로 리플렉션의 단점과 이를 어떤 식으로 제거할 수 있을지를 스스로 고민해보면 큰 도움이 되실 거에요.


상속

우리가 만드는 소프트웨어는 변경이 용이하고 유연해야만 합니다. 그것이 하드웨어와의 큰 차이점이죠.

상속은 자바가 제공하는 매우 강력한 기능이지만 양날의 검이 될 수 있습니다.요 부분에 대해서는 정리된 글들이 많으니 한번 찾아보시길 추천드립니다.간단히 설명드리자면 최상위 객체에 변경이 생길 경우 하위 객체에도 그 변경이 모두 적용됩니다.

우리는 Menu가 변경되는 것에 CustomerMenu가 영향받는 것을 원하지 않습니다.하지만 상속을 사용하게된다면 이 영향은 불가피한 영역이 되어버릴 수 있습니다.

이를 위해 자바는 interface라는 좋은 기능을 제공하는데요.interface를 사용해 공통된 기능을 추출하고 추상적으로 구현한다면 훨씬 변경에 강하며 유지보수가 쉬워집니다.

여기까지 힌트를 드렸으니 만약 처음부터 다시 구현한다고 생각한다면 어떤식으로 클래스들의 관계를 설계하실지 한번 천천히 생각해보시면 좋을 것 같습니다!!


책임과 역할

객체 지향을 처음 배울 때 흔히 듣는 말이 인간의 세계와 동일한 구조를 가지고 있다고들 말하는데요.

우리가 각자의 특성이 있는 것처럼 객체 지향 세상에서도 각자의 역할과 책임이 존재합니다.

클래스를 만들고 설계할 때 해당 클래스가 어떤 식으로 동작할 것이며 어떤 클래스들과 유기적인 의존관계를 맺고 있을 지에 대해 고민해보면 좋을 것 같습니다.


if와 for문

if나 for문을 많이 사용해 Depth가 깊어질수록 코드는 복잡해지고 어려워집니다.이런 상황이 발생했을 때가 바로 리팩토링이 필요하다는 신호인데요.😀

하나의 메서드에 적절한 책임을 부여하고 이를 제외한 나머지 코드는 새로운 메서드로 구현하는 식으로 잘게 쪼개면 좀 더 깔끔한 코드가 될 수 있습니다.(이는 객체를 분리할 때도 마찬가지겠죠??)

지수님의 코드에서 가장 Depth가 깊었던 groupByClass를 예시로 한번 들어볼께요~우리가 원하는 해당 메서드의 동작은 아래와 같습니다.

  • 고객의 정보를 통해 해당하는 고객이 속하는 그룹을 찾는다.
  • 해당 그룹에 고객 객체를 넣는다.

크게 2가지 덩어리로 쪼갤 수 있을 것 같은데요.생각해보면 결국 모든 고객을 한번은 체크해야하므로 외부for문은 필요할 것 같습니다.내부 for문에 있는 고객의 정보를 바탕으로 어떤 그룹에 속하는지를 검증하는 로직부터 차근차근 별도의 메서드로 쪼개는 것부터 시작하면 됩니다.쪼개면서 해당 메서드가 이 클래스에 존재하는 것이 맞는지를 곰곰히 생각해보면서 각 객체간의 흐름도 고민해보면 더 큰 도움이 될 거에요.

객체 지향 세상에서는 함수의 호출을 메시지를 던진다고 표현하곤 하는데, 이걸 여기에 적용하면 됩니다.적절한 메서드에게 고객의 정보를 던지고(같은 객체의 메서드일 수도 다른 객체의 메서드일 수도 있습니다.)이를 바탕으로 판단된 그룹을 다시 반환하고 이를 반환받은 곳에서 고객의 정보를 삽입해주는 식인거죠!

그림이나 직접 설명을 드리면 더 좋을 것 같은데, 글로만 적자니 조금 장황해지는 것 같아 죄송하네요😭

 

구체적으로 수정해야 할 부분

 

  • [ ] 리플렉션 사용하지 않기
  • [ ] ClassifedCustomersGroup, ClassifiedCustomers 객체 없애고 Group객체가 자신에게 속한 고객의 정보를 가지고 있게 하기
    • [ ] Group에게 자신의 그룹에 속한 고객의 정보를 담을 수 있는 Customers[]를 하나 추가해주고, 내부 메서드를 구현해 해당 메서드로 고객 객체를 넘긴다.
    • [ ] 해당 메서드는 자신이 가지고 있는 Parameter를 이용해 고객이 해당 기준을 만족한다면 Customers[]에 추가해주는 식으로 구현
  • [ ] 정렬 메서드가 호출될 때 마다 매번 새로운 Comparator 객체가 생성되는거 비효율적
  • [ ] A, D의 축약어 사용하지 않고 ASC, DECS로 변경
  • [ ] 한 클래스에서 내림차순과 오름차순 적용할 수 있게 하라
  • [ ] 내부 클래스보다는 분류기들을 한 패키지로 모아 별도의 객체로 관리하는것이 추후 유지보수에 좋다.
  • [ ] ClassifiedCustomersGroup과 ClassifiedCustomers를 제거한다면 해당 객체의 compare()를 호출하는 곳은 Custoemrs 가 될 것
  • [ ] else if 대신에 early-return 사용해서 깔끔하게 코드 스타일 변경
  • [ ] 자동 정렬 기능 사용 - Ctrl + Alt + L
  • [ ] 주석 정리
  • [ ] 사용하지 않는 import 모두 정리 - Ctrl + Alt + O
  • [ ] MAX_CUSTOMERS 라는 네이밍을 DEFAULT_CUSTOMERS_SIZE로 변경
  • [ ] Customer find 메서드를 Arrays.stream(customers)와 filter를 적절히 사용하여 변경
  • [ ] 줄 띄워쓰기도 다 깔끔하게 코드 포멧팅을 적용
  • [ ] 불필요한 생성자 제거
  • [ ] 싱글톤 패턴을 사용하려한마면 staitc final 키워드를 적용하자
  • [ ] null이 들어왔을때 비정상적인 상황으로 판단하는 validation 추가하면 좋을 듯, Customer의 생성자에서 하면 될 것
  • [ ] customer update, delete에서 무한 루프 발생 해결
  • [ ] 대소문자에 관계 없이 입력을 처리할 수 있으면 좋을 것

 

 

 

느낀점

 

강사님이 직접 프로젝트를 라이브코딩 하는 것을 보고, 아주 작은 단위로 함수로 만든다는 점이 가장 기억에 남았다.

중복을 최대한 줄이고 코드의 재사용을 최대화 하려고 하는 것이 느껴졌다. 일반화하는 느낌...?

다음은 내가 정리한 강사님이 코드를 쓰는 방법이다. 

 

 

  • 일단, 구현해야 할 기능을 쪼개서 생각한다.
  • 그리고 그렇게 쪼갠 기능을 함수로 만든다. 
  • 함수 하나에 여러 기능을 넣지 않고, 함수 하나당 하나의 기능을 담당하게 한다. 
  • 함수의 위치를 항상 고려한다.(어떤 객체가 함수를 가져야 할지)
  • 기능을 구현할 때 마다 나올 수 있는 예외를 생각하고 처리한다. 

 

나도 위의 것을 생각하며 코드를 짜야겠다는 생각이 든다. 

이를 참고해서 받은 피드백을 반영할 예정이다. 

 

 

'Java' 카테고리의 다른 글

[Java] MultiValueMap이란  (0) 2022.11.17
[Java] 스트림  (0) 2022.10.31
[Java] 컬렉션 프레임워크 활용  (0) 2022.10.20
[Java] 배열(심화)  (1) 2022.10.05
[Java] 자바 입출력  (0) 2022.10.02