Clean Code : 매개 변수가 적은 함수 [닫기]


48

나는 Robert C. Martin 의 Clean Code 의 첫 번째 장을 읽었으며 그것이 꽤 좋은 것 같지만 의심의 여지가 있습니다. 가능한 한, 3 개 이상의 매개 변수가 함수 (너무 과장되고 이상적이라고 생각)에 비해 너무 많음을 제안하기 때문에 궁금해하기 시작했습니다 ...

전역 변수를 사용하고 함수에 많은 인수를 전달하는 방법은 프로그래밍 방식이 좋지 않지만 전역 변수를 사용하면 함수의 매개 변수 수를 크게 줄일 수 있습니다 ...

그래서 나는 당신이 그것에 대해 생각하는 것을 듣고 싶었습니다. 글로벌 변수를 사용하여 함수의 매개 변수 수를 줄이는 것이 가치가 있습니까? 어떤 경우입니까?

내가 생각하는 것은 몇 가지 요소에 달려 있다는 것입니다.

  • 소스 코드 크기
  • 함수 평균의 매개 변수 수입니다.
  • 기능의 수.
  • 동일한 변수가 사용되는 빈도.

필자의 의견으로는 소스 코드 크기가 비교적 작은 경우 (600 줄 미만의 코드) 많은 함수가 있고 동일한 변수가 매개 변수로 전달되고 함수에 많은 매개 변수가 있으므로 전역 변수를 사용하는 것이 좋습니다. 알고 싶니...

  • 당신은 내 의견을 공유합니까?
  • 소스 코드가 더 큰 다른 경우에 대해 어떻게 생각하십니까?

추신 . 나는 이 게시물을 보았고 제목은 매우 유사하지만 그는 내가 알고 싶은 것을 묻지 않습니다.


144
대안은 글로벌이 아니라 인수를 객체로 통합하는 것이라고 생각합니다. 아마 postLetter(string country, string town, string postcode, string streetAddress, int appartmentNumber, string careOf)냄새 나는 버전의 제안 일 것 입니다 postLetter(Address address). 계속해서 책을 읽으면, 그런 말이 되길 바랍니다.
Nathan Cooper

3
@DocBrown 나는 Bob 아저씨가 3 개 이상의 매개 변수를 사용하지 말고 전역 변수를 사용하여 문제를 해결한다고 말하는 것과 같은 것을 의미하기 위해 질문을했습니다. :-) 저자는 아래 답변에서 언급 한 것처럼이 문제를 해결할 더 좋은 방법이 있는지 알지 못할 것 같습니다.
bytedev

9
다이아몬드에 새겨지지 않은 n 개 이하의 매개 변수는 경험 법칙 (n 값은 n)입니다. 위임장에 대한 좋은 조언을 착각하지 마십시오. 많은 매개 변수는 일반적으로 하나의 함수 / 메소드에서 너무 많은 코드 냄새입니다. 사람들은 추가 호출의 추가 오버 헤드를 피하기 위해 여러 기능으로 분리되는 것을 피했습니다. 더 이상이 성능을 많이 사용하는 응용 프로그램은 거의 없으며 프로파일 러는 추가 전화를 피해야하는시기와 장소를 알려줄 수 있습니다.
Jared Smith

14
이것은 이런 종류의 판단이없는 규칙의 문제점을 보여줍니다. 그것은 판단이없는 '솔루션'의 문을 엽니 다. 함수에 많은 인수가있는 경우 일반적으로 함수뿐만 아니라 사용중인 컨텍스트의 차선책을 나타낼 수 있습니다. 해결책은 필요한 경우 코드를 리팩토링하는 것입니다. 어떻게해야하는지에 대한 단순하고 일반적인 판단없는 규칙을 제시 할 수는 없지만 'N 개 이상의 주장'이 좋은 규칙이라는 것을 의미하지는 않습니다.
sdenham

4
함수에 너무 많은 매개 변수가있는 경우, 그중 일부는 관련되어 있으며 객체로 그룹화되어 여러 데이터 조각을 캡슐화하는 단일 매개 변수가되어야합니다. 여기에 세 번째 옵션이 있습니다.

답변:


113

나는 당신의 의견을 공유하지 않습니다. 내 의견으로는 전역 변수를 사용하는 것은 설명하는 자질에 관계없이 더 많은 매개 변수보다 나쁜 습관입니다. 필자의 이유는 더 많은 매개 변수가 메소드를 이해하기 어렵게 만들 수 있지만 전역 변수는 테스트 가능성, 동시성 버그 및 긴밀한 결합을 포함하여 코드에 많은 문제를 일으킬 수 있다는 것입니다. 함수의 매개 변수 수에 관계없이 전역 변수와 본질적으로 같은 문제는 없습니다.

... 동일한 변수가 매개 변수로 전달됩니다

디자인 냄새 일 있습니다. 시스템의 대부분의 기능에 동일한 매개 변수가 전달되는 경우 새 구성 요소를 도입하여 처리해야하는 교차 절단 문제가있을 수 있습니다. 전역 변수를 도입하는 건전한 추론으로 많은 변수에 동일한 변수를 전달한다고 생각하지 않습니다.

귀하의 질문을 편집 한 결과 전역 변수를 도입하면 코드의 가독성이 향상 될 수 있음을 나타 냈습니다. 동의하지 않습니다. 전역 변수의 사용법은 구현 코드에 숨겨져 있지만 함수 매개 변수는 서명에 선언되어 있습니다. 기능은 이상적으로 순수해야합니다. 매개 변수에서만 작동해야하며 부작용이 없어야합니다. 순수한 함수가있는 경우 하나의 함수 만보고 함수에 대해 추론 할 수 있습니다. 함수가 순수하지 않으면 다른 구성 요소의 상태를 고려해야하며 추론하기가 훨씬 더 어려워집니다.


좋아, 다른 의견을 듣는 것이 좋지만 디자인 냄새 에 대해서는 인공 지능의 방법으로 해결되는 C 문제로 프로그래밍하고 있으며 거의 ​​항상 동일한 행렬, 배열 또는 변수를 사용하는 많은 함수를 사용하는 경향이 있습니다. 함수에 매개 변수로 전달합니다.)이 변수를 일반적인 개념 / 구조체 또는 공용체와 같은 개념 안에 넣을 수 있다고 생각하지 않기 때문에 더 나은 디자인을 만드는 방법을 모릅니다. 그래서이 경우 전역 변수를 사용하는 것이 가치가 있다고 생각하는 이유이지만 대부분 틀릴 수 있습니다.
OiciTrap

1
그것은 디자인 문제처럼 들리지 않습니다. 나는 여전히 함수에 매개 변수를 전달하는 것이 가장 좋은 디자인이라고 생각합니다. 설명하는 AI 시스템에서 시스템 조각을 테스트하기 위해 단위 테스트를 작성하는 것이 유용하다는 것을 알았으며 가장 쉬운 방법은 매개 변수를 사용하는 것입니다.
사무엘

96
더 많은 매개 변수는 서브 루틴을 이해하기 어렵게 만들고, 전역 변수는 전체 프로그램, 즉 모든 서브 루틴 을 이해하기 어렵게 만듭니다.
Jörg W Mittag

2
일부 함수가 12 개 이상의 매개 변수를 사용하는 코드베이스를 유지 관리합니다. 함수를 호출해야 할 때마다 다른 창에서 해당 파일을 열어야 매개 변수를 지정 해야하는 순서를 알 수 있습니다. intellisense와 같은 것을주는 IDE를 사용하거나 매개 변수라는 이름의 언어를 사용하면 그렇게 나쁘지 않지만 모든 기능에 대해 12 개의 매개 변수가 어떤 순서인지 기억할 수 있습니까?
Jerry Jeremiah

6
그럼에도 불구하고 "Clean Code"의 권장 사항에 대해 OP가 오해하는 것은 당연한 것으로 보인다. 그 책에서 함수 매개 변수를 전역 변수로 바꾸는 권장 사항이 없다고 확신합니다.
Doc Brown

68

전염병과 같은 전역 변수는 피해야 합니다 .

I (3처럼 4) 인수의 수에 엄격한 제한을 두지 것입니다,하지만 당신은 수있는 경우, 최소로 유지하려면.

사용하여 struct(S) (또는 C ++ 객체의) 단일 엔티티로 그룹화 및 변수 (참조)이 전달 함수. 일반적으로 함수는 함수에 무언가를 수행하도록 지시하는 몇 가지 다른 매개 변수와 함께 구조 또는 객체 (몇 가지 다른 요소가있는)를 전달합니다 struct.

좋은 냄새, 깨끗하고 모듈 식 코드를 위해서는 단일 책임 원칙을 고수하십시오 . 구조체 (또는 객체), 함수 및 소스 파일을 사용하십시오. 그렇게하면 함수에 전달 된 자연수의 매개 변수가 분명해집니다.


5
구조체에 숨겨진 수십 개의 매개 변수를 전달하고 명시 적으로 전달하는 것의 주요 차이점은 무엇입니까?
Ruslan

21
@Ruslan 응집력.
abuzittin gillifirca

9
그리고 수십 개의 매개 변수 대신 하나의 매개 변수를 하위 기능에 전달할 수 있으므로 함수를 더 작은 함수로 리팩토링 할 가능성이 높습니다. 위치 인수를 사용하면 매개 변수를 혼합 할 위험이 줄어 듭니다.
한스 올슨

8
괜찮지 만 Structs에서 일관성을 보장해야합니다. Struct로 그룹화 된 매개 변수가 '관련'되어 있는지 확인하십시오. 경우에 따라 둘 이상의 Struct를 사용할 수 있습니다.
Andrew Dodds

8
@abuzittingillifirca 자동으로 응집력을 얻지 못합니다. 매개 변수를 구조체에 넣는 유일한 정당화가 매개 변수를 특정 함수에 전달하는 것이라면 응집력은 환상적 일 것입니다.
sdenham

55

우리는 구문이 아니라인지 부하에 대해 이야기하고 있습니다. 그래서 질문은 ... 무엇입니까 이다 이러한 맥락에서 매개 변수는?

매개 변수는 함수의 동작에 영향을주는 값입니다. 매개 변수가 많을수록 가능한 값 조합이 많을수록 함수에 대한 추론이 어려워집니다.

그런 의미에서 함수가 사용하는 전역 변수 매개 변수입니다. 그것들은 서명에 나타나지 않고 구성 순서, 액세스 제어 및 remanence 문제가있는 매개 변수입니다.

상기 매개 변수가 교차 절단 문제 라고하는 경우가 아니라면 모든 것이 사용하지만 아무것도 변경하지 않는 프로그램 전체 상태 (예 : 로깅 개체)가 아니라면 함수 매개 변수를 전역 변수로 바꾸면 안됩니다. 그것들은 여전히 ​​매개 변수이지만 nastier입니다.


11
당신에게 +1, 화장실이나 화장실이 똑같습니다. 양의 옷에서 늑대를 지적하는 좋은 일.
Jared Smith

1
많은 parms와 전역 변수가 모두 나쁘다는 것을 +1. 그러나 나는 무언가를 분명히하고 싶다. 대부분의 언어에서 기본 매개 변수는 기본적으로 값으로 전달되고 (Java), 다른 매개 변수에서는 명시 적으로 값으로 전달할 수 있습니다 (PL / SQL). 반면에 전역 프리미티브는 항상 참조로 액세스됩니다 (그렇습니다). 따라서 최소한 기본 유형의 매개 변수는 항상 전역 변수보다 안전합니다. 물론 둘 또는 세 개의 매개 변수를 갖는 것이 냄새이지만, 12 개의 매개 변수를 갖는 것은 리팩토링되는 큰 냄새이다.
Tulains Córdova

4
절대적으로 전역 변수는 숨겨진 매개 변수입니다.
Bill K

+1 지금까지는 전역 변수를 사용하여 데이터를 전달하는 MATLAB 시뮬레이션을 보았습니다. 어떤 변수가 어떤 함수에 대한 매개 변수인지 알기가 어려워 결과를 완전히 읽을 수 없었습니다.
Cort Ammon

34

귀하의 질문은 오해에 근거합니다. "클린 코드"에서 Bob Martin은 반복되는 함수 매개 변수를 전역으로 대체 할 것을 제안하지 않습니다. 이는 정말 끔찍한 조언입니다. 그는 함수 클래스의 개인 멤버 변수 로 대체 할 것을 제안 합니다. 또한 작고 응집력있는 클래스 (일반적으로 600 줄의 코드보다 작음)를 제안 하므로 이러한 멤버 변수는 전역 변수가 아닙니다.

따라서 "전역 변수를 사용하는 것이 그만한 가치가 있습니다"라는 600 줄 미만의 맥락에서 의견을 가지고 있다면 , Uncle Bob의 의견을 완벽하게 공유 할 수 있습니다. 물론, "최대 3 개의 매개 변수"가 이상적인 숫자인지, 그리고이 규칙이 때때로 작은 클래스에서도 너무 많은 멤버 변수를 초래하는 경우에는 논쟁의 여지가 있습니다. IMHO 이것은 절충점이며 선을 그릴 위치에 대한 엄격한 규칙은 없습니다.


10
나는 실제 인수로 사는 대신 매개 변수를 생성자에 채워서 클래스를 상태 화하는 것을 선호하는 이유를 결코 이해하지 못했습니다. 이것은 항상 복잡성이 엄청나게 증가함에 따라 나를 때렸습니다. (내가 본 실제 예제는 데이터베이스 연결 객체로, 의존성 주입과 결합하면 불가능한 프로그램을 통해 데이터베이스의 상태를 추적하려고 시도했습니다.) 그러나 Clean Code 는 그 특정 것에 대해 더 많이 말할 것입니다. 제목. 물론 세계는 상황을 정립시키는 것과 관련하여 더 나쁜 선택입니다.
jpmc26

2
@ jpmc26 : 클래스가 너무 커지고 멤버 변수가 너무 많을 경우 "복잡성이 엄청나게 증가"할 뿐이므로 더 이상 응집력이 없습니다.
Doc Brown

4
응답은 많은 클래스에 퍼져있는 상태를 관리하는 데 어려움 (변경 가능 할 수도 있음)을 무시한다고 생각합니다. 함수가 인수뿐만 아니라 객체가 어떻게 구성 (또는 수명 동안 수정되었는지)에 의존하는 경우 특정 호출을 할 때 현재 상태를 이해하는 것이 더 어려워집니다. 이제 통화가 수행 할 작업을 파악하기 위해 다른 객체의 구성 을 추적 해야합니다. 인스턴스 변수를 추가하면 객체를 생성하고 즉시 버리지 않는 한 프로그램의 상태가 적극적으로 증가합니까?
jpmc26

3
@ jpmc26 리팩토링 할 때 규칙적으로 사용하는 한 가지 패턴은 생성자가 컨텍스트를 설정하는 것처럼 작동한다는 것입니다. 그런 다음 메서드 인수는 작업에 따라 다릅니다. 객체는 상태가 결코 변하지 않기 때문에 정확하게 상태를 유지하지는 않지만 일반적인 작업을이 컨테이너의 메소드로 옮기면 가독성이 크게 향상됩니다 (컨텍스트는 한 번만 설정되고 파이썬의 컨텍스트 관리자와 유사 함). 객체의 메소드를 여러 번 호출합니다.
이즈 카타

3
+1 멤버 변수가 전역 변수가 아님을 분명히 말하십시오. 많은 사람들이 자신이 있다고 생각합니다.
Tulains Córdova

34

많은 매개 변수를 갖는 것은 바람직하지 않은 것으로 간주되지만 실제 문제를 해결하지는 않지만 새로운 문제를 유발 하기 때문에 필드 또는 전역 변수로 바꾸는 것이 훨씬 더 나쁩니다 .

많은 매개 변수를 갖는 것이 문제 자체는 아니지만 문제가있는 증상 입니다. 이 방법을 고려하십시오.

Graphics.PaintRectangle(left, top, length, height, red, green, blue, transparency);

7 개의 매개 변수를 갖는 것은 확실한 경고 신호입니다. 기본 문제는 이러한 매개 변수가 독립적이지 않지만 그룹에 속한다는 것입니다. left그리고 topA와 함께 속한다 Position-structure, length그리고 heightA와 Size구조와 red, blue그리고 greenA와 Color구조. 그리고 아마도 Color투명성은 Brush구조에 속합니까? 아마 PositionSizeA의 함께 속해 Rectangle있는 경우에 우리는 심지어으로 돌려 고려할 수, 구조 Paint온 방법 Rectangle대신 객체? 따라서 다음과 같이 끝날 수 있습니다.

Rectangle.Paint(brush);

임무 완수! 그러나 중요한 것은 실제로 전체 설계를 개선했으며 매개 변수 수를 줄인 결과 그 결과 입니다. 근본적인 문제를 다루지 않고 매개 변수 수를 줄이면 다음과 같이 할 수 있습니다.

Graphics.left = something;
Graphics.top = something;
Graphics.length = something;
...etc
Graphics.PaintRectangle();

여기서 우리는 매개 변수 수를 똑같이 줄 였지만 실제로 디자인을 악화 시켰습니다 .

결론 : 모든 프로그래밍 조언과 규칙에 대해 근본적인 추론을 이해하는 것이 정말로 중요합니다.


4
+1 좋고 건설적이고 이해하기 쉬운 비 이론적 답변.
AnoE

1
말할 것도없이, 길이와 높이 속성을 모두 갖는 "정사각형"은 무엇입니까? :)
와일드 카드

1
일부 답변 (즉, 함수 호출 전에 일부 구조 / 객체에 대한 많은 할당)에 의해 암시되는 명백한 세 번째 방법이 더 나쁘지 않다는 것을 인정하여 +1.
benxyzzy

@Wildcard : 감사합니다. 문제를 혼동하지 않도록 "직사각형"으로 변경했습니다.
JacquesB

7

전역 변수를 사용하여 함수의 매개 변수 수를 줄이는 것이 가치가 있습니까?

아니

이 책의 첫 장을 읽었습니다

책의 나머지 부분을 읽었습니까?

전역은 숨겨진 매개 변수입니다. 그들은 다른 고통을 유발합니다. 그러나 여전히 고통입니다. 이 규칙을 피할 수있는 방법을 생각하지 마십시오. 그것을 따르는 방법에 대해 생각하십시오.

매개 변수 란 무엇입니까?

물건입니다. 라벨이 잘 붙은 상자에. 상자에 물건을 넣을 수있는 상자의 수는 왜 중요합니까?

운송 및 취급 비용입니다.

Move(1, 2, 3, 4)

읽을 수 있다고 말해주세요. 계속 해봐

Move(PointA, PointB)

그 이유입니다.

이 트릭을 소개 매개 변수 객체 라고 합니다 .

그리고 네가하는 모든 것이 매개 변수를 세는 것이라면 단지 속임수입니다. 계산해야 할 것은 아이디어입니다! 추상화! 한 번에 얼마나 생각하니? 간단하게 유지하십시오.

이제 이것은 같은 카운트입니다.

Move(xyx, y)

아야! 그건 정말 나쁘다! 여기서 무엇이 잘못 되었습니까?

아이디어의 수를 제한하는 것만으로는 충분하지 않습니다. 그들은 분명한 아이디어 여야합니다. 도대체 xyx는 무엇입니까?

이제 이것은 여전히 ​​약합니다. 이것에 대해 생각하는 더 강력한 방법은 무엇입니까?

기능은 작아야합니다. 그보다 작지 않습니다.

엉클 밥

Move(PointB)

왜 함수가 실제로 필요한 것보다 더 많은 기능을 수행하게합니까? 단일 책임 원칙은 수업에만 국한된 것이 아닙니다. 진지하게, 하나의 기능이 때로는 10 개의 관련 매개 변수가있는 과부하 된 악몽으로 변하는 것을 막기 위해 전체 아키텍처를 변경하는 것이 좋습니다. 일부 기능은 다른 기능과 함께 사용할 수 없습니다.

함수에서 가장 일반적인 줄 수가 1 인 코드를 보았습니다. 나는 당신이 그런 식으로 글을 써야한다고 말하는 것이 아니라, esh, 글로벌이 당신이이 규칙을 따를 수있는 유일한 방법이라고 말하지 마십시오. 해당 기능을 올바르게 리팩토링하지 마십시오. 당신은 당신이 할 수 있다는 것을 알고 있습니다. 몇 가지 기능으로 나눌 수 있습니다. 실제로 몇 개의 물체로 변할 수 있습니다. 지옥의 일부를 완전히 다른 응용 프로그램으로 나눌 수도 있습니다.

이 책은 매개 변수를 세도록 지시하지 않습니다. 그것은 당신이 일으키는 고통에주의를 기울여야한다고 말하고 있습니다. 고통을 해결하는 것은 문제를 해결합니다. 단순히 하나의 고통을 다른 고통과 교환 할 때주의하십시오.


3
"책의 나머지 부분을 읽었습니까?" 귀하의 질문은 내 게시물의 첫 8 단어에서 답변됩니다 ...
OiciTrap

나는 문제를 작은 조각으로 분해하는 것이 전적으로 동의한다. 객체는 이러한 조각을 구성하고 그룹화하는 데 실제로 도움이 될 수 있으며 단일 개념적 단위를 연결되지 않은 조각이 아닌 매개 변수로 전달할 수도 있습니다. 3 개 이상의 매개 변수가있는 메소드를 보면 개미가 생깁니다. 5는 내 디자인이 허물어 졌음을 나타내며 다른 리팩토링이 필요합니다. 매개 변수 수와 같은 디자인 문제를 해결하는 가장 좋은 방법은 물건을 더 작고 간단한 단위 (클래스 / 방법)로 리팩터링하는 것입니다.
Bill K

2
이 답변의 톤을 향상시킬 수 있습니다. 매우 갑작스럽고 가혹합니다. 예를 들면 다음과 같습니다. "그것을 읽을 수 있다고 말해주세요. 계속 시도하십시오." 매우 공격적으로 보이며 "위 / 아래의 두 함수 호출 중 어느 것이 더 읽기 쉬운가?"로 다시 쓸 수 있습니다. 당신은 침략없이 포인트를 가로 질러야합니다. OP는 방금 배우려고합니다.
Kyle A

OP도 깨어 있으려고 노력하고 있다는 것을 잊지 마십시오.
candied_orange

4

매개 변수를 줄이기 위해 전역 변수를 사용하지는 않습니다. 그 이유는 모든 함수 / 명령에 의해 전역 변수가 변경 될 수 있기 때문에 함수 입력을 신뢰할 수없고 함수가 처리 할 수있는 범위를 벗어난 값이되기 쉽습니다. 함수 실행 중 변수가 변경되었고 함수의 절반이 다른 절반과 다른 값을 가진 경우 어떻게됩니까?

반면에 매개 변수를 전달하면 변수의 범위가 자체 함수로만 제한되어 함수 만 호출 된 매개 변수를 수정할 수 있습니다.

매개 변수 대신 전역 변수를 전달해야하는 경우 코드를 다시 디자인하는 것이 좋습니다.

내 두 센트.


"매개 변수를 줄이기 위해 전역 변수를 사용하지 않을 것"이라고 전적으로 동의합니다. 불필요한 커플 링을 만듭니다.
bytedev

2

나는 이것에 관해 삼촌 밥과 함께 있고 3 개 이상의 매개 변수를 피해야한다는 것에 동의합니다 (함께 3 개 이상의 매개 변수를 거의 사용하지 않습니다). 단일 기능에 많은 매개 변수가 있으면 유지 관리 문제가 더 커지고 기능이 너무 많은 / 책임이 많은 냄새 일 수 있습니다.

OO 언어의 메소드에서 3 이상을 사용하는 경우 매개 변수가 어떤 식 으로든 서로 관련이 없으므로 실제로 객체를 전달해야합니까?

또한 더 작은 (작은) 함수를 만들면 함수의 매개 변수가 3 개 이하인 경향이 있습니다. 추출 기능 / 방법은 친구입니다 :-).

더 많은 매개 변수를 갖는 라운드를 얻는 방법으로 전역 변수를 사용하지 마십시오! 그것은 나쁜 습관 하나를 더 나쁜 것으로 바꾸고 있습니다!


1

많은 함수 매개 변수의 유효한 대안은 매개 변수 개체 를 도입하는 입니다. 이것은 (거의) 모든 매개 변수를 다른 많은 메소드에 전달 하는 구성된 메소드 가있는 경우 유용 합니다.

간단한 경우에 이것은 오래된 DTO 만 속성으로 갖는 간단한 DTO입니다.


1

전역 변수를 사용하면 항상 코딩하기 쉬운 방법 (특히 작은 프로그램에서)으로 보이지만 코드를 확장하기가 어렵습니다.

예, 배열을 사용하여 한 엔터티의 매개 변수를 바인딩하여 함수의 매개 변수 수를 줄일 수 있습니다.

function <functionname>(var1,var2,var3,var4.....var(n)){}

위의 기능이 편집되고 [Associative Array 사용]으로 변경됩니다.

data=array(var1->var1,
           var2->var2
           var3->var3..
           .....
           ); // data is an associative array

function <functionname>(data)

나는 Robert bristow-johnson의 대답에 동의 합니다. 구조를 사용하여 단일 엔터티에 데이터를 바인딩 할 수도 있습니다.


1

PHP 4에서 예를 들어, 함수 서명을 살펴보십시오 mktime().

  • int mktime ([ int $hour = date("H") [, int $minute = date("i") [, int $second = date("s") [, int $month = date("n") [, int $day = date("j") [, int $year = date("Y") [, int $is_dst = -1 ]]]]]]] )

혼란스럽지 않습니까? 이 기능을 "시간 만들기"라고하지만 일, 월 및 연도 매개 변수와 세 개의 시간 매개 변수가 필요합니다. 그들이 어떤 순서로 들어가는 지 기억하는 것이 얼마나 쉬운가요? 당신이 보면 mktime(1, 2, 3, 4, 5, 2246);? 다른 것을 언급하지 않고도 이해할 수 있습니까? 되어 224624 시간의 시간 "22시 46분"으로 해석? 다른 매개 변수는 무엇을 의미합니까? 그것은 객체로서 더 나을 것입니다.

PHP 5로 이동하면 이제 DateTime 객체가 있습니다. 그 방법은 두 가지입니다 사이라고 setDate()하고 setTime(). 그들의 서명은 다음과 같습니다.

  • public DateTime setDate ( int $year , int $month , int $day )
  • public DateTime setTime ( int $hour , int $minute [, int $second = 0 ] )

여전히 매개 변수의 순서가 가장 큰 것에서 가장 작은 것임을 기억해야하지만 크게 개선되었습니다. 한 번에 6 개의 매개 변수를 모두 설정할 수있는 단일 방법은 없습니다. 이렇게하려면 두 번의 별도 호출을해야합니다.

Bob 아저씨가 말한 것은 평평한 구조를 피하는 것입니다. 관련 매개 변수는 하나의 객체로 그룹화해야하며, 3 개 이상의 매개 변수가있는 경우 의사 객체가있을 가능성이 높으므로 더 큰 분리를 위해 적절한 객체를 생성 할 수 있습니다. PHP는 별도의 없지만 DateTime클래스를, 당신은이 고려할 수 DateTime정말로 포함되어 Date객체와 Time객체를.

다음 구조를 가질 수 있습니다.

<?php
$my_date = new Date;
$my_date->setDay(5);
$my_date->setMonth(4);
$my_date->setYear(2246);

$my_time = new Time;
$my_time->setHour(1);
$my_time->setMinute(2);
$my_time->setSecond(3);

$my_date_time = new DateTime;
$my_date_time->setTime($my_time);
$my_date_time->setDate($my_date);
?>

매번 2 ~ 3 개의 매개 변수를 설정해야합니까? 한 시간 또는 하루 만 변경하려는 경우 이제 쉽게 변경할 수 있습니다. 예, 각 매개 변수가 다른 매개 변수와 작동하는지 확인하기 위해 오브젝트의 유효성을 검증해야하지만, 어쨌든 그랬습니다.

가장 중요한 것은 이해하기 쉽고 유지 관리가 쉬운가입니다. 맨 아래의 코드 블록은 단일 mktime()함수 보다 크지 만 이해하기가 훨씬 쉽다고 주장합니다. 프로그래머가 아닌 사람조차도 그 일을 수행하는 데 많은 어려움을 겪지 않을 것입니다. 목표는 항상 더 짧은 코드 나 더 영리한 코드가 아니라 유지 보수가 쉬운 코드입니다.

아, 그리고 글로벌을 사용하지 마십시오!


1

여기에 많은 좋은 대답이 있지만 대부분은 요점을 다루지 않습니다. 왜 이런 규칙이 필요한가? 그것은 범위에 관한 것이고, 의존성에 관한 것이며 적절한 모델링에 관한 것입니다.

인수에 대한 전역은 더 단순 해 보였지만 실제로는 복잡성을 숨 겼기 때문에 더 나쁩니다. 프로토 타입에서 더 이상 볼 수는 없지만 여전히 더 알고 있어야합니다 (더 이상 볼 수 없기 때문에 어렵습니다). 함수의 논리를 둘러 보는 것은 도움이되지 않습니다. 등 뒤에 방해가되는 다른 숨겨진 논리가 있어야합니다. 당신의 범위는 모든 곳으로 갔고 이제는 변수를 엉망으로 만들 수 있기 때문에 무엇이든지 의존성을 도입했습니다. 안좋다.

함수에 대해 유지해야 할 주요 사항은 프로토 타입과 호출을보고 그 기능을 이해할 수 있다는 것입니다. 따라서 이름은 명확하고 모호하지 않아야합니다. 그러나 더 많은 주장이있을수록 그것이하는 일을 이해하기가 더 어려워집니다. 그것은 당신의 머리의 범위를 넓히고, 너무 많은 일이 일어나고 있습니다. 그래서 당신은 숫자를 제한하고 싶습니다. 어떤 종류의 논증을 다루는가는 중요하지만 어떤 것은 다른 것보다 더 나쁩니다. 대소 문자를 구분하지 않는 처리를 허용하는 추가 선택적 부울은 함수를 더 이해하기 어렵지 않으므로 크게 다루기를 원하지 않습니다. 부수적으로, 열거 형의 의미는 호출에서 명백하기 때문에 열거 형은 부울보다 더 나은 인수를 만듭니다.

전형적인 문제는 엄청난 양의 인수로 새로운 함수를 작성하는 것이 아니라, 아직 해결하려는 문제가 실제로 얼마나 복잡한 지 알지 못할 때 몇 가지로 시작합니다. 프로그램이 발전함에 따라 인수 목록이 점차 길어지는 경향이 있습니다. 일단 모델이 마음에 설정되면 알고있는 안전한 참조이므로 모델을 유지하려고합니다. 그러나 돌이켜 보면 모델이 그렇게 크지 않을 수 있습니다. 논리에서 한 단계 나 빠졌고 엔티티를 인식하지 못했습니다. "OK ... 코드를 리팩토링하는 데 하루나 이틀 정도 소요될 수 있습니다. 또는이 인수를 추가하여 결국 올바른 작업을 수행하고 완료 할 수 있습니다. 지금은이 시나리오의 경우 이 메모를 판에서 떼어 내 스티커 메모를 끝까지 옮길 수 있습니다. "

두 번째 솔루션을 자주 사용할수록 더 많은 유지 보수 비용이 더 많이 들며 리 팩터가 더 어렵고 매력적이지 않게됩니다.

기존 기능에서 인수 수를 줄이기위한 보일러 플레이트 솔루션은 없습니다. 그것들을 화합물로 그룹화하는 것은 실제로 일을 쉽게하는 것이 아니라 카펫 아래의 복잡성을 닦는 또 다른 방법 일뿐입니다. 제대로하려면 전체 통화 스택을 다시보고 누락되었거나 잘못 된 것을 인식해야합니다.


0

여러 번 함께 보내진 많은 매개 변수를 그룹화하면 개선 된 것으로 나타났습니다.

  • 이 개념을 함께 사용하면 이러한 개념을 잘 설명 할 수 있습니다. 이러한 매개 변수를 함께 사용하면 관계가 있거나 전혀 함께 사용해서는 안됩니다.

  • 일단 객체를 사용하면 일반적으로 바보 같은 객체로 약간의 funtionality를 옮길 수 있습니다. 일반적으로 테스트하기 쉽고 응집력이 뛰어나고 커플 링이 적어 훨씬 더 좋습니다.

  • 다음에 새 매개 변수를 추가해야 할 때 많은 메소드의 서명을 변경하지 않고 포함시킬 좋은 위치가 있습니다.

따라서 100 % 작동하지 않을 수도 있지만이 매개 변수 목록을 객체로 그룹화 해야하는지 스스로에게 물어보십시오. 그리고 제발 객체 생성을 피하기 위해 Tuple과 같은 형식화되지 않은 클래스를 사용하지 마십시오. 객체 지향 프로그래밍을 사용하고 있으며 필요한 경우 더 많은 객체를 만들지 않아도됩니다.


0

모든면에서, 함수에 적은 수의 매개 변수가 있다는 점을 완전히 놓쳤습니다.

아이디어는 뇌는 한 번에 너무 많은 "활성 정보」를 개최 할 수 있다는 것입니다, 당신이있는 경우에 n 개의 함수에서 매개 변수를, 당신은 N 을 쉽고 정확하게 당신의 두뇌에 있어야합니다"활성 정보 "더 많은 조각을 코드 조각이 무엇을하고 있는지 이해하십시오 (코드 완성 (훨씬 더 나은 책, IMO)의 Steve McConnell은 메소드 본문에서 7 가지 변수에 대해 비슷한 것을 말합니다 : 우리는 거의 도달하지 않지만 더 이상 당신은 잃고 있습니다. 머리에 모든 것을 똑바로 유지하십시오).

적은 수의 변수는이 코드 작업에 필요한인지 요구 사항을 작게 유지할 수 있으므로보다 효율적으로 작업하거나 읽을 수 있습니다. 이것의 한 가지 원인은 잘 팩토링 된 코드가 더 적은 매개 변수를 갖는 경향이 있다는 것입니다 (예를 들어, 제대로 팩토링되지 않은 코드는 많은 것들을 엉망으로 묶는 경향이 있습니다).

값 대신 객체를 전달하면 아마도 두뇌에 대한 추상화 수준을 얻을 수 있습니다. 이제 를 알아야 합니다 . 검색 컨텍스트 내에있을 수있는 15 가지 속성에 대해 생각하는 대신 여기에서 사용할 수있는 SearchContext 가 있습니다.

전역 변수를 사용하려고 시도하면 완전히 잘못된 방향으로 진행되었습니다. 이제 함수에 너무 많은 매개 변수를 갖는 문제를 해결하지 않았을뿐만 아니라, 그 문제를 해결하여 훨씬 더 나은 문제로 던져 버렸습니다 .

이제 기능 수준에서 작업하는 대신 프로젝트의 전체 범위를 고려해야합니다 (간헐, 얼마나 끔찍한 지! 함수 (전역 변수 이름은 무엇입니까?)에서 당신 앞에 모든 정보가 없습니다 (이 함수를 호출 한 이후 다른 것으로 변경되지 않았기를 바랍니다).

전역 범위 변수는 프로젝트에서 볼 수있는 가장 최악의 것 중 하나입니다 (크거나 작음). 그것들은 적절한 스코프 관리를위한 장애를 나타내며, 이는 프로그래밍에 매우 기본적인 기술입니다. 그들. 아르. 악.

함수에서 매개 변수를 이동하고 전역에 배치하면 자신을 바닥 (또는 다리 또는 얼굴)에 쐈습니다. 그리고 하나님께서는 당신 이이 지구본을 다른 무언가를 위해 재사용 할 수 있다고 결정하는 것을 금하셨습니다 . 내 마음은 생각에 떨립니다.

가장 이상적인 것은 일을 쉽게 관리하는 것이며 전역 변수는 그렇게하지 않을 것입니다. 나는 그들이 당신이 반대 방향으로 가기 위해 할 수있는 최악의 일 중 하나라고 말하기 위해 갈 것입니다.


-1

인터페이스 간 마찰을 최소화하는 매우 효과적인 접근 방식 (JavaScript에서)을 발견했습니다. 모든 모듈에 대해 단일 인터페이스 함수 , 특히 단일 매개 변수 함수에 대해 균일 한 인터페이스 를 사용하십시오 .

여러 매개 변수가 필요한 경우 : 단일 개체 / 해시 또는 배열을 사용하십시오.

나랑 참아, 내가 트롤링하지 않겠다고 약속 해

"단일 매개 변수 기능이 무엇입니까?"또는 "1 배열과 다중 인수 기능 사이에 차이가 있습니까?"라고 말하기 전에

그래 아마도 시각적으로 미묘하지만 그 차이는 여러 가지입니다. 여기서 많은 이점을 살펴 봅니다.

분명히 일부 ppl은 3이 인수의 올바른 #이라고 생각합니다. 어떤 사람들은 그것이 2라고 생각합니다. 글쎄요. "아직 어떤 매개 변수가 arg [0]에 들어가는가?" 보다 엄격한 선언으로 인터페이스를 제한하는 옵션을 선택하는 대신.

좀 더 급진적 인 입장을 주장한다고 생각합니다. 위치 주장에 의존하지 마십시오. 나는 그것이 연약하다고 느끼고 빌어 먹을 논쟁의 위치에 대한 논쟁으로 이어진다. 그것을 건너 뛰고 함수와 변수의 이름에 대한 피할 수없는 싸움으로 바로 이동하십시오. 😉

진지하게 이름을 정한 후에는 다음과 같은 코드가 생길 것입니다.이 코드는 위치에 민감하지 않고 다소 자체 문서화되며 향후 매개 변수 변경 사항을 함수 내부에서 처리 할 수 ​​있습니다.

function sendMessage({toUser, fromUser, subject, body}) { }

// And call the method like so:
sendMessage({toUser: this.parentUser, fromUser: this.currentUser, subject: ‘Example Alert’})


6
명명 된 인수를 속이는 것이 실제로 하나의 인수 만 전달하는 것은 아닙니다.
JDługosz

내가 설정 한 목표를 달성하면 왜 "가짜"입니까? 명명 된 인수에 우선 순위를두고 있습니다. 위치 호출은 코드를 호출하는 것이 분명하지 않으며 이름이 지정된 함수 수를 사용하여 개발자는 기억해야 할 매개 변수가 어디에 있고 어떤 매개 변수가 있는지 기억하는 것이 도움이되지 않습니다. ... 결국 당신은 옵션 후, 필요한 카드를 추가하고 싶을 것입니다. 행운을 빕니다.
Dan Levy

2
명명 된 매개 변수는 강화 학습 트릭입니다. 인간은 단어 모음에 더 많은 의미를 부여합니다.
Dan Levy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.