함수 인수 수를 최소화하는 기술


13

Clean Code에서는 "함수에 대한 이상적인 인수 수가 0"이라고 쓰여 있습니다. 이유를 설명하고 이해하는 이유. 내가 따르는 것은이 문제를 해결하기 위해 4 개 이상의 인수로 메소드를 리팩터링하는 기술입니다.

한 가지 방법은 인수를 새 클래스로 추출하는 것이지만 클래스 급증으로 이어질까요? 그리고 이러한 클래스는 일부 명명 규칙 ( "데이터"또는 "정보"등으로 끝남)을 위반하는 이름으로 끝날 가능성이 있습니까?

다른 기술은 여러 함수가 사용하는 변수를 전용 멤버 변수로 만들어서 전달하지 않도록하는 것입니다. 그러나 변수의 범위가 확장되어 실제로 필요하지 않은 함수에 개방 될 수 있습니다.

함수 인수를 최소화하는 방법을 찾고, 그렇게하는 것이 좋은 이유를 받아 들였습니다.


21
Tbh 나는 깨끗한 코드에 전혀 동의하지 않습니다. 함수에 대한 인수 수가 0이면 함수에 부작용이 있고 어딘가에서 상태가 변경 될 수 있음을 의미합니다. 4 개 미만의 인수가 좋은 경험이 될 수 있음에 동의하지만, 정적이 아니며 8 가지 인수가있는 함수를 사용합니다. 상태가 변경되고 부작용이있는 인수가 0 인 비 정적 함수보다 정적이 아닙니다. .
wasatz

4
" Clean Code에서"함수에 대한 이상적인 인수 수는 0 "입니다. "정말? 너무 잘못되었습니다! 이상적인 매개 변수 수는 하나이며, 하나의 매개 변수에서 결정적으로 도출 된 리턴 값이 있습니다. 실제로 매개 변수의 수는 중요하지 않습니다. 중요한 것은 가능할 때마다 함수가 순수해야한다는 것입니다 (즉, 부작용없이 매개 변수에서만 반환 값을 도출 함).
David Arno

2
그 부작용은 바람직하지에서 잘 책은 ... 점에 나중에 이동하지 않습니다
닐 Barnwell


답변:


16

가장 중요한 것은 규칙이 아니라 지침이라는 것입니다.

메소드가 단순히 인수 취해야하는 경우 있습니다. +예를 들어 숫자에 대한 방법을 생각하십시오 . 또는 add수집 방법.

실제로, 두 개의 숫자를 더하는 것이 의미하는 것은 문맥에 따라 다르지만 (예 : ℤ 3 + 3 == 6, ℤ | 5 3 + 3 == 2 ) 실제로 더하기 연산자는 컨텍스트 대신에 두 개의 인수 를 취하는 컨텍스트 객체의 메소드 여야합니다 하나의 인수를 취하는 숫자에 대한 메소드.

마찬가지로, 두 객체를 비교하는 방법은 한 객체가 다른 객체를 인수로 취하는 방법이거나 컨텍스트의 방법으로 두 객체를 인수로 취하는 방법이어야합니다. 따라서 단순히 비교 방법을 갖는 것은 의미가 없습니다. 하나 이상의 논쟁.

즉, 메소드의 인수 수를 줄이기 위해 수행 할 수있는 몇 가지 작업이 있습니다.

  • 메소드 자체를 더 작게 만드십시오 . 어쩌면 메소드에 많은 인수가 필요한 경우 너무 많은 일을하고 있습니까?
  • 누락 된 추상화 : 인수가 서로 밀접하게 연관되어 있다면, 그것들이 함께 속해 있으며, 누락 된 추상화가 있습니까? 정식 교재 예 : 두 좌표 대신 Point객체를 전달하거나 사용자 이름과 이메일을 전달하는 대신 객체를 전달 IdCard합니다.
  • Object state : 여러 메소드에 인수가 필요한 경우 오브젝트 상태의 일부 여야합니다. 일부 메소드에서만 필요하지만 다른 메소드에서는 필요하지 않은 경우 오브젝트가 너무 많은 작업을 수행하고 실제로 두 개의 오브젝트 여야합니다.

한 가지 방법은 인수를 새 클래스로 추출하는 것이지만 클래스 급증으로 이어질까요?

도메인 모델에 여러 종류의 것들이 있다면 코드는 여러 종류의 객체로 끝납니다. 그것에 아무런 문제가 없습니다.

그리고 이러한 클래스는 일부 명명 규칙 ( "데이터"또는 "정보"등으로 끝남)을 위반하는 이름으로 끝날 가능성이 있습니까?

적절한 이름을 찾을 수 없으면 너무 많은 인수를 그룹화하거나 너무 적게 그룹화했을 수 있습니다. 그래서, 당신은 클래스의 조각이거나 둘 이상의 클래스를 가지고 있습니다.

다른 기술은 여러 함수가 사용하는 변수를 전용 멤버 변수로 만들어서 전달하지 않도록하는 것입니다. 그러나 변수의 범위가 확장되어 실제로 필요하지 않은 함수에 개방 될 수 있습니다.

동일한 인수에서 작동하는 메소드 그룹과 그렇지 않은 다른 메소드 그룹이있는 경우 다른 클래스에 속할 수 있습니다.

"아마도"라는 단어를 얼마나 자주 사용 했습니까? 이것이 규칙이 아닌 지침입니다. 아마도 4 개의 매개 변수를 사용하는 방법이 완벽 할 것입니다!


7
@ BrunoSchäpper : 물론 : (1) " 메소드 자체를 더 작게 만드십시오. 아마도 메소드가 많은 인수를 필요로한다면 너무 많은 일을하고 있습니까? ". 매개 변수의 수는 이것에 대한 나쁜 테스트입니다. 선택적 / 부울 매개 변수와 많은 코드 행은 너무 많은 방법을 나타내는 강력한 지표입니다. 많은 매개 변수는 기껏해야 약한 매개 변수입니다. (2) " 객체 상태 : 여러 방법으로 인수가 필요한 경우 객체 상태의 일부 여야합니다 ." 아니, 아니, 세 번 객체 상태를 최소화하십시오. 기능 매개 변수가 아닙니다. 가능하면 객체 상태를 피하기 위해 매개 변수를 통해 모든 메소드에 값을 전달하십시오.
David Arno

추가를 위해 제시 한 예가 잘못되었습니다. add자연수에 대한 기능과 add정수의 링 기능은 n 개의 서로 다른 두 가지 유형에 대한 두 개의 서로 다른 기능의 행동은 MOD. "문맥"의 의미를 이해하지 못합니다.
gardenhead

Thx @DavidArno. 1) 그 자체로는 강력한 지표가 아니라 동의했다. 그럼에도 불구하고 좋은 사람. 나는 종종 몇 가지 방법을 보았습니다. 객체 상태가 없습니다. 좋은 점이지만 2) 더 나은 옵션 IMHO는 이러한 메소드를 리팩토링하고 암시 적 상태를 새 클래스로 옮기면 이러한 모든 매개 변수를 명시 적 인수로 사용합니다. 하나의 공개 0 인수 메소드와 많은 0 대 1 인수 내부 메소드로 끝납니다. 국가는 공개적이거나 전 세계적이거나 오랫동안 살아 있지 않지만 코드는 훨씬 깨끗합니다.
Bruno Schäpper

6

객체가 암시적인 인수이므로 인수가 0 인 것은 부작용을 의미하지 않습니다. 예를 들어 스칼라의 불변 목록에 제로-어리 티 (zero-arity) 방법이 몇 개 있는지 살펴보십시오 .

"렌즈 초점 맞추기"기술이라고하는 유용한 기술 중 하나입니다. 카메라 렌즈의 초점을 맞출 때 너무 초점을 맞추면 실제 초점 포인트를 쉽게 확인한 다음 올바른 위치로 되돌릴 수 있습니다. 소프트웨어 리팩토링도 마찬가지입니다.

특히 분산 버전 제어를 사용하는 경우 소프트웨어 변경을 실험하기가 쉽고, 모양이 마음에 드는지 확인하고, 그렇지 않은 경우 물러나지 만, 어떤 이유로 사람들은 종종 그 일을 꺼려합니다.

현재 질문의 맥락에서, 그것은 여러 개의 분리 함수가있는 0 또는 하나의 인수 버전을 먼저 쓰는 것을 의미합니다. 그러면 가독성을 위해 어떤 함수를 결합 해야하는지 쉽게 알 수 있습니다.

저자는 또한 테스트 주도 개발을 대변하는 사람입니다. 사소한 테스트 사례로 시작하기 때문에 처음에는 저 배터리 기능을 생성하는 경향이 있습니다.


1
"렌즈 초점 맞추기"비유와 마찬가지로-특히 리팩토링시 근접 렌즈 대신 광각 렌즈를 사용하는 것이 중요합니다. 매개 변수 수를 살펴 보는 것은 너무 근접한 것입니다.
tofro

0

단순히 (그리고 순진하게-또는 맹목적으로 말해야하는) 접근법은 함수에 대한 인수의 수를 줄이는 것을 목표로합니다. 많은 수의 인수를 갖는 함수에는 아무런 문제가 없습니다. 그것들이 논리에 필요하다면, 그것들도 필요합니다 ... 긴 매개 변수 목록은 가독성을 위해 올바르게 형식화되고 주석 처리되어있는 한 전혀 걱정하지 않습니다.

인수의 전부 또는 일부가 하나의 고유 한 논리 엔티티에 속하고 일반적으로 프로그램 전반에 걸쳐 그룹 주위에 전달하는 경우, 어쩌면 약간의 용기에 그룹을에 의미가 있습니다 - 일반적으로 구조체 또는 기타 객체입니다. 일반적인 예는 일종의 메시지 또는 이벤트 데이터 유형일 수 있습니다.

이러한 접근 방식을 쉽게 극복 할 수 있습니다. 일단 이러한 운송 컨테이너로 물건을 포장하고 포장을 풀면 가독성이 향상되는 것보다 더 많은 오버 헤드가 발생한다는 사실을 알게되면 아마도 너무 멀었을 것입니다.

OTOH, 큰 매개 변수 목록은 프로그램이 제대로 구성되지 않았 음을 나타내는 신호일 수 있습니다. 이러한 많은 수의 매개 변수를 필요로하는 기능 은 너무 많은 작업을 수행하려고하므로 여러 개의 작은 기능으로 분할해야합니다. 매개 변수 수에 대해 걱정하는 것보다 여기에서 시작하겠습니다.


5
물론 맹목적으로 줄어든 논거 수는 잘못된 것입니다. 그러나 나는 "다수의 주장을 갖는 함수에는 아무런 문제가 없다" 고 동의하지 않는다 . . 내 의견으로는, 많은 수의 인수로 함수를 칠 때 모든 경우의 99,9 %에서 의도적으로 함수의 인수 수를 줄이는 코드 구조를 개선하는 방법이 있습니다.
Doc Brown

@DocBrown 그렇기 때문에이 마지막 단락과 여기에서 시작하는 권장 사항이 있습니다 .... 그리고 다른 하나 : 아마도 MS Windows API에 대해 프로그램을 시도한 적이 없습니다.)
tofro

"매우 많은 매개 변수를 필요로하는 기능이 너무 많은 일을하려고하기 때문에 여러 개의 작은 기능으로 분할되어야합니다." 실제로는 몇 가지 작은 함수를 호출하는 스택보다 높은 다른 함수로 끝나지 않더라도 완전히 동의합니다. 그런 다음 이들을 객체로 리팩터링 할 수 있지만 해당 객체에는 ctor가 있습니다. 빌더 blah blah blah를 사용할 수 있습니다. 요점은 그것이 무한 회귀라는 것입니다. 어딘가에, 소프트웨어가 작업을 수행하는 데 필요한 많은 값이 있으며, 어떻게 든 그 기능에 도달해야합니다.
Neil Barnwell

1
@NeilBarnwell 이상적인 경우 (가치 리팩토링) 10 개의 인수가 필요한 함수를 각각 3-4 개의 인수가 필요한 3 개로 분할 할 수 있습니다. 이상적이지 않은 경우에는 각각 10 개의 인수가 필요한 세 개의 함수로 끝납니다 (그러면 혼자 두십시오). 상위 스택 인수와 관련하여 : 동의-반드시 그런 것은 아니지만 인수가 어딘가에서 올 수 있으며 검색은 스택의 어딘가에있을 수 있으며 적절한 위치에 넣어야합니다-마일리지 변화하는 경향이 있습니다.
tofro

소프트웨어 로직에는 매개 변수가 네 개 이상 필요하지 않습니다. 컴파일러 만 가능합니다.
닥터

0

마법의 방법은 없습니다. 올바른 아키텍처를 발견하려면 문제 영역을 마스터해야합니다. 이것이 리팩토링하는 유일한 방법입니다 : 문제 영역 마스터하기. 현재 아키텍처가 잘못되었거나 잘못되었다는 사실은 4 가지가 넘는 매개 변수 일뿐입니다.

유일한 예외는 컴파일러 (메타 프로그램)와 시뮬레이션입니다. 여기서 한계는 이론적으로 8이지만 아마도 5입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.