11.1 질의 함수와 변경 함수 분리하기
- 우리는 외부에서 관찰할 수 있는 겉보기 부수효과(observerable side effect)가 전혀 없이 값을 반환해주는 함수를 추구해야 한다. (...중략...) 겉보기 부수효과가 있는 함수와 없는 함수는 명확히 구분하는 것이 좋다. (...중략...) 이를 명령-질의 분리(command-query sepration)라 하는데 p.413
- 명령 - 질의 분리는 꽤나 유용한 행동지침입니다. 결과 값을 가져오는 것과 객체 내부 상태 변경을 한 번에 하고 있으면 사용하는 입장에서는 결과를 예측하기 어려워집니다... 그래서 두 개의 함수로 분리시키는 것이 유지보수에 좋습니다.
11.3 플래그 인수 제거하기
- 함수의 인자로 boolean 값을 넘기는 관례는 피해야 합니다. 함수가 한꺼번에 여러가지를 처리한다고 대 놓고 공표하기 때문입니다. 플래그가 참이면 이걸하고 거짓이면 저걸 한다는 플래그 인수는 피해야 한다.
- 플래그 인수는 함수에 Bool / String / Enum 등을 함께 넘겨서 로직을 분기하는 방법입니다. 저도 코딩하면서 이런 식으로 함수를 자주 작성했던 것 같은데, 이런 구현 방식이 호출하는 입장에서는 결과를 예측하기 어렵게 만듭니다.
- 내가 플래그 인수를 싫어하는 이유가 있다. 호출할 수 있는 함수들이 무엇이고 어떻게 호출해야 하는지를 이해하기가 어려워지기 때문이다. 나는 API를 익힐 때 주로 함수 목록부터 살펴보는데, 플래그 인수가 있으면 함수들의 기능 차이가 잘 드러나지 않는다. 사용할 함수를 선택한 후에도 플래그 인수로 어떤 값을 넘겨야 하는지를 또 알아내야 한다. p.422
- 단순한 분기인 경우에 함수를 여러 개로 나누면 됩니다. 이건 간편한 편이고 만약 아주 복잡한 로직이 얽혀 있어서 함수로 나누기 어려운 경우도 있습니다. 그런 경우 다음과 같이 래핑 함수를 만들어줄 수 있습니다.
func rushDeliveryDate(order: Order) -> Date {
return deliveryDate(order: order, isRush: true)
}
func regularDeliveryDate(order: Order) -> Date {
return deliveryDate(order: order, isRush: false)
}
11.5 매개변수를 질의 함수로 바꾸기
- 주의사항이 하나 있다. 대상 함수가 참조 투명(referential transparency) 해야 한다는 것이다. 참조 투명이란 '함수에 똑같은 값을 건네 호출하면 항상 똑같이 동작한다'는 뜻이다. 이런 함수는 동작을 예측하고 테스트하기가 훨씬 쉬우니 이 특성이 사라지지 않도록 주의하자. 따라서 매개변수를 없애는 대신 가변 전역 변수를 이용하는 일은 하면 안 된다. p.434
- 질의 함수는 참조 투명해야 합니다. 같은 입력값에는 같은 출력 값을 만들어 내는 개념입니다. 이렇게 하면 프로그램을 예측하기 쉽습니다.
- 참조 투명성에 대한 정의를 위키백과에서 좀 더 찾아봤습니다.
- 참조 투명성과 참조 투명도는 컴퓨터 프로그램의 일부 속성이다. 프로그램 동작의 변경 없이 관련 값을 대체할 수 있다면 표현식을 참조 상 투명하다고 할 수 있다. 그 결과, 참조 상 투명한 함수를 평가하게 되면 동일한 인자에 대해 동일한 값을 반환해야 한다. 그러한 함수를 순수 함수라고 부른다. 참조상 투명하지 않은 표현식은 참조상 불투명하다고 한다. 수학에서 모든 함수 응용은 수학적 함수를 구성하는 요소의 정의에 의해 참조 상 투명하다. 하지만, 프로그래밍에서는 그런 케이스가 항상 맞는 것은 아니며, 함축된 의미의 오해를 피하고자 프로시저와 메소드라는 용어가 사용된다. 함수형 프로그래밍에서는 오로지 참조 상 투명한 함수 만이 고려된다. 어떤 프로그래밍 언어들은 참조 투명성을 보장하기 위한 수단을 제공한다. 어떤 함수형 프로그래밍 언어들은 모든 함수에 대해 참조 투명성을 강제하기도 한다.
- 참조 투명한 함수: 순수 함수
- 메소드: 리턴값 O
- 프로시저: 리턴값 X. 수행하는 절차를 목적으로 함
- 함수형 프로그래밍: 참조 투명한 함수만 고려됨
11.6 질의 함수를 매개변수로 바꾸기
이 책은 얄궂은 구석이 있는데요. 하나의 방법을 말하고 나서 그와 반대되는 방법을 바로 다음 소챕터에서 말하고 있습니다.
그러니까 상황에 따라서 trade-off를 해가면서 리팩토링을 적용하라는 것입니다.
'질의 함수를 매개변수로 바꾸기' 바로 앞의 소주제는 거울처럼 반대되는 개념인 '매개변수를 질의 함수로 바꾸기'였습니다.
- 프로그램을 더 잘 이해하게 됐을 때 더 나은 쪽으로 개선하기 쉽게 설계해두는 게 중요하다. p.438
- 현재의 설계가 잘못된 것이 드러났을 때, 후회하고 비판하는 것보다 즉각적으로 개선하는 자세가 중요하다는 것을 배웠습니다.
- 프로그래머가 판단했을 때 그 상황에서 최선의 설계를 할 것이기 때문에 미래에 코드를 봤을 때 개선할 부분이 보이는 것은 당연합니다.
11.9 함수를 명령으로 바꾸기
- OOP에서 명령 자체를 객체로 표현할 수 있는데요.
- OOP를 처음 공부하면서 개념이나 분기, 명령들을 객체로 표현할 수 있다는 사실에 놀라웠던 기억이 납니다.
- 여기서는 함수를 Command 객체로 만들어서 사용합니다.
- 하지만 유연성은 (언제나 그렇듯) 복잡성을 키우고 얻는 대가임을 잊지 말아야 한다. 그래서 일급 함수와 명령 중 선택해야 한다면, 나라면 95%는 일급 함수의 손을 들어준다. 내가 명령을 선택할 때는 명령보다 더 간단한 방식으로는 얻을 수 없는 기능이 필요할 때뿐이다. p.449
그런데 Command 객체보다 일급 함수를 쓰는 것이 더 나을 때가 많다고 합니다ㅋㅋ...
꼭 필요한 때만 객체로 분리해서 사용하고 나머지의 경우 일급 함수를 사용해야겠네요.
'Engineering WIKI > Book' 카테고리의 다른 글
[일래스틱 스택 6 입문] 3장. 유사도 검색 (84) | 2023.09.17 |
---|---|
기초부터 다지는 엘라스틱서치 운영 (1 ~ 2장) / 훑어보기 및 기본동작 (58) | 2023.09.07 |
[일래스틱 스택 6 입문] 2장. 일래스틱서치 시작하기 (2) | 2023.08.22 |
[일래스틱 스택 6 입문] 1장. 일래스틱 소개 (1) | 2023.08.22 |
리팩토링 2판 - Chapter 10 (조건부 로직 간소화) (0) | 2022.10.20 |
리팩토링 2판 - Chapter 9 (데이터 조직화) (0) | 2022.10.20 |
리팩토링 2판 - Chapter 8 (기능이동) (0) | 2022.10.20 |
리팩토링 2판 - Chapter 7 (캡슐화) (0) | 2022.10.20 |