Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[9주차] 08. 기능 이동 (~8.4) #8

Open
DaehunGwak opened this issue Nov 21, 2021 · 2 comments
Open

[9주차] 08. 기능 이동 (~8.4) #8

DaehunGwak opened this issue Nov 21, 2021 · 2 comments
Labels

Comments

@DaehunGwak
Copy link
Contributor

진도

  1. 기능 이동

방식

  • 코멘트로 자유롭게 느낀점 (좋았단 점) 을 적어주시면 됩니다.
  • 질문, 다른 좋은 참고자료, 실무 적용 사례 등을 공유해주셔도 좋습니다.
@minkukjo
Copy link
Contributor

느낀점

함수 옮기기는 원래도 하고 있던 부분이라 특별할 건 없었다.
객체지향 개발을 하다보면 객체가 적절한 책임과 역할을 다하고 있는지를 항상 확인해봐야한다.
그런 의미에서 종종 함수 옮기기를 실행하는데, 여기서는 위임이라는 것을 사용해서 기존 로직을 다른 곳으로 옮기고, 옮겨진 메소드를 호출하는 형태를 보여줬는데 이런 식의 위임 패턴을 사용하는구나라는 생각이 들었다. ( 우리 회사 코드에도 종종 보임 )
필드 옮기기도 함수 옮기기와 비슷한 느낌이었다. 재밌는 부분은 CustomerContract를 생성자에서 new로 인스턴스를 구성해주는 것을 보았는데, 코틀린의 경우 생성자의 인자가 2개면 반드시 넣어야해서 ( nullable을 사용하지 않는 경우 ) 이러한 패턴을 코틀린에 적용하려니 조금 애매한 부분이 있었다. (결국 생성자 인자가 3개가 되는 현상 발생.. 그 중에 1개는 private 프로퍼티)

class Customer(
        val name: String,
        private val discountRate: Double,
        val contract: CustomerContract = CustomerContract(LocalDateTime.now(), discountRate)
)

문장을 함수 옮기기는 함수 추출을 할 때 어떤 과정으로 진행하면 깔끔하게 되는지를 보여주는 부분이었다.
아무래도 Intellij가 강력하다보니 함수 추출, 이름 변경까지 IDE의 도움을 받아서 쉽게 진행할 수 있었다.
문장 함수 옮기기는 앞에꺼 반대니까 패스~

코드 : https://github.com/minkukjo/refactoring/commits/master

@DaehunGwak
Copy link
Contributor Author

느낀점

  • 문장이라고 하길래 처음에 이해가 안되었는데 Statement...
  • 요즘 기존 코드를 고치면서 해당 클래스에 있어도 되는 코드인가? 다른 곳으로 옮겨야하지 않는가? 라는 생각이들때가 많은데, 이번에 정리한 리팩터링 신호들을 자주 참고해봐야겠다.
  • 아 이것도 결국 클래스 역할, 메서드 역할로 귀결되는 구나 라고 생각이 되었고, 기본이 중요하구나를 다시 깨달음
8.1 ~ 8.4 정리

8.1 함수 옮기기

  • 좋은 설계의 핵심은 모듈화가 얼마나 잘되어 있는가를 뜻하는 모듈성 이다
    • 모듈성은 수정할 때 관련 기능과 깊이를 작은 일부만 이해해도 가능하게 해주는 능력
  • 프로그램의 이해도가 높아질수록 요소들을 더 잘 묶는 새로운 방법을 알게됨
  • 객체 지향 프로그래밍의 핵심 모듈화 컨텍스트는 클래스
  • 필요에 따라 새로운 컨텍스트를 만들어야할 때도 있음

함수를 옮겨야 하는 신호

  • 어떤 함수가 자신이 속한 A 요소보다 B 요소를 더 많이 참조할 때
  • 다음 업데이트 때 바뀌리라 예상되는 위치가 생각날 때

옮길 장소를 정하기 어려울 때

  • 옮겨야 할 대상 함수의 현재 컨텍스트와 후보 컨텍스트를 둘러보면 도움
  • 살펴보면 도움되는 요소
    • 대상 함수를 호출하는 곳
    • 대상 함수가 호출하는 함수들
    • 대상 함수가 사용하는 데이터
  • 정 어려우면 한 컨텍스트에 일단 몰아보기, 이후 인사이트를 얻을 확률이 높음

함수 옮기기 리팩터링 절차

  1. 옮길 대상 함수가 현재 컨텍스트에 사용 중인 모든 프로그래밍 요소를 살펴보기. 요소 중 같이 옮길 것이 있는지 고민
  2. 선택한 함수가 다형 메서드인지 확인 (같이 옮겨줘야 하므로)
  3. 옮겨질 컨텍스트(target context)로 선택한 함수를 복붙. 타겟 함수가 타겟 컨텍스트에 어울리도록 다듬기 (이름변경, 파라미터 변경 등)
    • target function: 복붙된 함수
    • source function: 기존 옮겨질 대상 함수
  4. 정적 분석
  5. 소스 컨텍스트에 타겟 함수를 참조할 방법을 찾아 반영
  6. 소스 함수를 타겟 함수의 위임 함수가 되도록 수정
  7. 테스트
  8. 소스 함수를 인라인할지 고민
    • 제거하는 편이 맞지만 너무 많은 의존성이 있으면 다 파악하기 어려움

8.2 필드 옮기기

  • 프로그램의 진짜 힘은 데이터 구조에서 나온다
  • 데이터 구조를 잘못 선택하면
    • 아귀가 맞지 않는 데이터를 다루기 위한 코드로 범벅
    • 데이터 구조 자체의 역할도 파악하기 어려움
  • 경험과 도메인 주도 설계 같은 기술이 가장 적합한 데이터 구조를 만들어낼 때 도움
  • 현재 데이터 구조가 적절치 않음을 깨달으면 바로 수정

필드를 옮겨야하는 신호

  • 함수에 어떤 레코드를 옮길 때 마다 따라 붙는 필드가 있을 때
  • 한 레코드를 변경하려 할 때 다른 레코드도 변경할 때

필드 옮기기 리팩터링 절차

  1. 소스 필드가 캡슐화되어 있지 않다면 캡슐화
  2. 테스트
  3. 타겟 객체에 필드, 접근자 메서드 생성
  4. 정적 검사
  5. 소스 객체에 타겟 객체를 참조할 수 있는지 확인
    • 간단치 않다면 타겟 객체를 저장할 새필드를 소스 객체에 생성
  6. 접근자들이 타겟 객체를 사용하도록 수정
  7. 테스트
  8. 소스 필드 제거
  9. 테스트

8.3 문장을 함수로 옮기기

Move Statements into Function

  • 문장이라고 표현해서 헷갈리는데, 여기서 말하는 문장은 Statement 라고 해석하자
  • 중복 제거 방법 중 하나
  • 해당 리팩터링을 했는데 여러 변형이 다시 나눠야하는 순간이 오면 다시 역으로 문장을 호출하는 곳으로 옮기면 된다 (8.4)
  • 문장을 함수로 옮기려면 대상 함수의 일부라는 확신이 있어야함
  • 애매하다면 매당 문장들과 피함수를 통째로 하나의 함수로 추출할 수 있다 (6.1)

문장을 함수로 옮겨야하는 신호

  • 특정 함수를 호출하는 코드가 나올 때 마다 그 앞이나 뒤에 똑같은 코드가 발생할 때

8.4 문장을 호출한 곳으로 옮기기

Move Statements to Callers

  • 8.3 과 반대 리팩터링
  • 초기엔 응집도가 높고 한 가지 일만 수행하던 함수가 둘 이상의 다른 일을 수행하게 바뀔 수 있다
  • 단순하게는 호출자로 일부 문장을 넘길 수 있다
  • 책임이 불분명해지거나 할 땐, 호출자와 호출 대상의 경계를 다시 그어야 할 때도 있음
    • 이럴 땐 함수 인라인 (6.2) 후, 문장 슬라이드 (8.6) + 함수 추출하기 (6.1) 로 더 적합한 경계를 설정할 수 있다

문장을 호출한 곳으로 옮겨야 하는 신호

  • 한가지 일을 수행하던 함수가 둘 이상의 다른 일을 수행하게 될때 고려 가능
  • 여러 곳에서 사용하던 함수가 일부 호출자에서 다르게 동작하도록 바뀌어야 할 때

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants