때때로 (드물게), 적절한 양의 매개 변수를 취하는 함수를 만드는 것이 가장 좋은 경로 인 것 같습니다. 그러나 내가 할 때 종종 매개 변수의 순서를 임의로 선택하는 것처럼 느낍니다. 나는 가장 중요한 매개 변수를 먼저 사용하여 "중요도 순서"로 이동합니다.
더 좋은 방법이 있습니까? 선명도를 높이는 매개 변수를 정렬하는 "모범 사례"방법이 있습니까?
때때로 (드물게), 적절한 양의 매개 변수를 취하는 함수를 만드는 것이 가장 좋은 경로 인 것 같습니다. 그러나 내가 할 때 종종 매개 변수의 순서를 임의로 선택하는 것처럼 느낍니다. 나는 가장 중요한 매개 변수를 먼저 사용하여 "중요도 순서"로 이동합니다.
더 좋은 방법이 있습니까? 선명도를 높이는 매개 변수를 정렬하는 "모범 사례"방법이 있습니까?
답변:
일반적으로 사용하십시오 .
실제 테스트 인 함수 테스트를 작성하십시오.
뭔가 당신이 실제로 원하는 그 기능을 수행합니다 .
그리고 어떤 순서로 그것들을 내려 놓았는지보십시오.
비슷한 기능을하는 기능을 이미 가지고 있거나 알고 있지 않는 한.
이 경우 : 적어도 첫 번째 주장에 대해서는 이미 수행 한 내용을 준수 하십시오.
예를 들어 모두 문서 / 객체 / 파일 포인터 / 값 시리즈 / 좌표 를 첫 번째 인수로 사용합니까? 신을 위해서 그러한 주장에 따르십시오 .
동료 와 미래의 자기 자신을 혼동 하지 마십시오 .
나는 항상 같은 우선 순위를 갖지는 않지만 일반적으로 이러한 규칙을 따릅니다. 나는 그것이 자동 사고 과정 이라고 생각하고 공개 API 디자인을 제외하고는 그것을 너무 많이 생각하지 않습니다 .
특히 OOP 에서 작업 또는 메시지 에 대한 의미 상 의미에 따라 매개 변수를 선택 하십시오. 잘 명명 된 매개 변수를 가진 잘 명명 된 메소드의 서명은 다음과 같아야합니다.
(이러한 이유로, 원시 형식 대신 사용자 정의 유형 또는 별명을 사용하면 서명의 표현성이 향상 될 수 있습니다.)
가장 "중요한"매개 변수가 먼저 나온다 (또는 다음으로 ...)
특히 명명 된 매개 변수는 없지만 위치 매개 변수의 기본값을 가질 수있는 언어에서 빈도도 중요합니다. 즉, 매개 변수의 순서가 다양하지 않으며 N 번째 매개 변수의 기본값을 강제로 적용하려는 경우 분명히 N + 1 매개 변수를 설정할 수 없습니다 (언어에 자리 표시 자 매개 변수 개념이있는 경우 제외) ).
좋은 소식은 일반적으로 빈도가 중요도와 관련되어 있으므로 이전 시점과 밀접한 관련이 있다는 것입니다. 그리고 적절한 의미를 갖도록 API를 작성하는 것은 아마도 당신에게 달려 있습니다.
메소드 / 함수가 일부 입력을 가져 와서 출력을 생성하고 후자가 "반환"(반환 문을 통해) 또는 "thrown"(예외 시스템 사용)하지 않는 경우 통과 옵션이 남습니다. 다른 매개 변수 (또는 입력 매개 변수)를 사용하여 호출자에게 값을 다시 보냅니다. 이는 시맨틱과 관련이 있으며 대부분의 경우 첫 번째 매개 변수가 출력을 정의하고 마지막 매개 변수가 출력을 수신하는 것이 좋습니다.
또한 매개 변수를 줄이고 의미를 최대화하는 다른 방법은 기능적인 방법을 사용하거나 빌더 패턴 을 정의하는 것이므로 입력을 명확하게 쌓고 출력을 정의하고 필요할 때 검색 할 수 있습니다.
(글로벌 변수를 언급하지 않는 이유는 무엇입니까? 왜 사용합니까?)
사용성
ZJR의 조언 을 따르면 위의 대부분이 자연스럽게 표시됩니다 . 사용하십시오!
리팩토링 고려
매개 변수 순서가 걱정된다면 위의 문제와 API가 잘못 설계되었다는 사실 에서이 문제가 발생할 수 있습니다. 매개 변수가 너무 많으면 구성 요소 화 / 모듈화 및 리팩토링 될 수 있습니다 .
성능 고려
일부 언어의 구현은 매개 변수를 사용할 때 런타임 메모리 관리에 매우 중요한 영향을 미칩니다. 따라서 많은 언어의 스타일 북이 매개 변수 목록을 간단하고 짧게 유지하는 것이 좋습니다 이유 입니다. 예를 들어 최대 4 개의 매개 변수에서 나는 당신이 이유를 알아내는 연습으로 남겨 둡니다.
Clean Code 의 권장 사항에 대한 Bevan의 답변 과 언급 은 확실히 관련이 있습니다!
나는 매개 변수 순서에 대한 걱정이 잘못된 것에 대해 걱정한다는 것을 정중하게 제출합니다.
밥 아저씨의 " 깨끗한 코드 "( Clean Code)에서 그는이 방법이 두 개 이상의 주장을 가져서는 안된다는 주장을 설득력있게 주장한다. 이 경우 주문은 명백하거나 중요하지 않습니다.
그러나 불완전하게, 나는 Uncle Bob의 조언을 따르려고 노력하고 있습니다-그리고 그것은 코드를 향상시키고 있습니다.
드문 경우지만 메소드에 더 많은 정보 가 필요한 것 같으면 매개 변수 객체를 도입 하는 것이 좋습니다. 일반적으로 이것이 알고리즘의 핵심 인 새로운 개념 (객체)을 발견하는 첫 번째 단계라는 것을 알았습니다.
IN 매개 변수를 먼저, OUT 매개 변수를 두 번째로 넣으려고합니다. 자연 createPoint(double x, double y)
순서도 createPoint(double y, double x)
있습니다. 예를 들어 .
addAllTo(target, something1, something2)
.
이 특정 주제와 관련하여 문서화 된 "모범 사례"를 본 적이 없지만 제 개인 표준은 사용중인 방법에 나타나는 순서대로 또는 방법이 데이터 계층으로 전달 데이터베이스 스키마 또는 데이터 계층 메소드에 나타나는 순서대로 나열합니다.
또한 메소드의 여러 과부하가있는 경우 일반적인 방법은 각 메소드 오버로드에 대해 각기 다른 메소드가 끝에 추가되는 모든 (또는 대부분의) 메소드에 공통적 인 매개 변수로 시작하여 매개 변수를 나열하는 것입니다. :
void func1(string param) { }
void func2(string param, int param2) { }
void func3(string param, string param3) { }
void func3(string param, int param2, string param3) { }
나는 종종 const
매개 변수를 먼저 (즉, 값으로 전달하는 매개 변수) 배치 한 다음 참조로 전달하는 C / C ++ 규칙을 따릅니다 . 이것은 함수를 호출하는 올바른 방법 일 필요는 없지만 각 컴파일러가 매개 변수를 처리하는 방법에 관심이 있다면 규칙에 대한 다음 링크 및 / 또는 매개 변수가 스택으로 푸시되는 순서를 살펴보십시오.
http://msdn.microsoft.com/en-us/library/zthk2dkh%28v=vs.80%29.aspx
나는 보통 "저렴한 모양이 아닌 것"매개 변수 순서로 진행합니다. 메소드 / 함수 정의로 이동해야하는 횟수가 적을수록 좋습니다. 그리고 작은 툴팁이 뜨면 (VS) 그렇게하는 것이 더 쉬운 방법을 설명하는 매개 변수의 이름을 지정하는 것이 좋습니다.
매개 변수의 선과 선이있는 경우 다른 디자인을 고려할 수 있습니다. 물러서서 더 많은 기능 / 방법으로 나누는 방법을 살펴보십시오. 단지 아이디어이지만 함수에 12 개의 매개 변수가 있으면 거의 항상 매개 변수 문제가 아니라 디자인 문제입니다.
때때로 (드물게), 적절한 양의 매개 변수를 취하는 함수를 만드는 것이 가장 좋은 경로 인 것 같습니다.
이 방법 에서 SRP 를 위반한다는 몇 가지 매개 변수를 사용하는 것이 종종 명확한 지표 입니다. 많은 매개 변수가 필요한 방법은 한 가지 작업 만 수행 할 가능성이 없습니다 . 예외는 수학 함수 또는 구성 방법 일 수 있으며, 실제로 여러 매개 변수 가 필요합니다. 악마가 성수를 피하기 때문에 여러 매개 변수를 피할 것입니다. 메서드 내에서 더 많은 매개 변수를 사용할수록 메서드가 너무 복잡 할 가능성이 높아집니다. 복잡성이 클수록 유지 관리가 어렵고 바람직하지 않습니다.
그러나 내가 할 때 종종 매개 변수의 순서를 임의로 선택하는 것처럼 느낍니다. 나는 가장 중요한 매개 변수를 먼저 사용하여 "중요도 순서"로 이동합니다.
priniple에서는 무작위 로 선택 하고 있습니다. 물론 매개 변수 A 가 매개 변수 B 보다 관련 이 있다고 생각할 수 있습니다 . 그러나 B 가 가장 관련성이 높은 매개 변수 라고 생각하는 API 사용자에게는 해당되지 않을 수 있습니다 . 따라서 순서를 고르는 데주의를 기울여도 다른 사람들에게는 무작위로 보일 수 있습니다.
더 좋은 방법이 있습니까? 선명도를 높이는 매개 변수를 정렬하는 "모범 사례"방법이 있습니까?
몇 가지 방법이 있습니다.
a) 사소한 경우 : 두 개 이상의 매개 변수를 사용하지 마십시오.
b) 지정한 언어를 선택하지 않았을 때 매개 변수 이름이 지정된 언어를 선택했을 가능성이 있습니다 . 이것은 훌륭한 구문 설탕 으로 매개 변수 순서의 중요성을 완화시킬 수 있습니다.fn(name:"John Doe", age:36)
모든 언어가 그러한 멋을 허용하는 것은 아닙니다. 그럼 무엇?
c) Dictionary / Hashmap / Associative Array 를 매개 변수로 사용할 수 있습니다 . 예를 들어 Javascript는 다음을 허용합니다 fn({"name":"John Doe", age:36})
. (b)에서 멀지 않은 거리.
d) 물론 Java 와 같이 정적으로 유형이 지정된 언어로 작업하는 경우 . Hashmap을 사용할 수 있지만 HashMap<String, Object>
매개 변수의 유형이 다르고 캐스팅해야 할 때 형식 정보 가 느슨합니다 (예 : 작업 시).
다음 논리적 단계는 Object
적절한 속성이나 구조체 와 같은 더 가벼운 무언가 (예 : C # 또는 C / C ++) 와 함께 (Java를 사용 하는 경우) 전달하는 것 입니다.
경험 법칙 :
1) 가장 좋은 경우-분석법에 매개 변수 가 전혀 필요 하지 않습니다.
2) 좋은 경우-방법에는 하나의 매개 변수가 필요합니다
3) 허용 가능한 경우-분석법에 두 개의 매개 변수가 필요합니다
4) 다른 모든 사례는 리팩토링되어야한다
필자는 일반적으로 특정 느낌에 따라 "느낌"(으로 표시 될 수 있음 ORDER BY required DESC, SOME_MAGIC_FEELING(importancy,frequency)
) 에 따라 중요도 및 사용 빈도를 결합하여 측정하는 것보다 먼저 필요한 것을 먼저 주문합니다 .
그러나 다른 사람들이 지적 했듯이이 문제를 일으키는 근본적인 문제는 너무 많은 매개 변수 (IMHO,> 3이 너무 많음)를 사용하는 것이며 이것이 해결해야 할 실제 문제라고 생각합니다. Rebecca Murphey의 블로그에 흥미로운 게시물 이 있습니다 .
나는 당신이 1-3 개의 주장만을 가질 때, 정확한 순서는 분명하고 당신은 옳은 것을 "느끼고"있다고 생각합니다.
@Wyatt Barnetts의 답변과 비슷하지만 메소드에 대한 몇 가지 매개 변수 또는 매우 명시 적 매개 변수 이상인 대신 객체를 전달하는 것이 좋습니다. 이는 일반적으로 업데이트 / 유지 관리가 쉽고 읽기 가 쉬우 며 주문에 대한 걱정이 없습니다 . 또한 메소드에 너무 많은 매개 변수는 코드 냄새 이며 이를 수정하기 위해 따를 수 있는 공통 리팩토링 패턴 이 있습니다.
명시 적 예 :
public int add(int left, int right)
{
return left + right;
}
이것은 꽤 명확하게 정의 된 예이고 덧셈은 교환 적이므로 (순서는 중요하지 않음) 그냥 따라 가십시오.
그러나 더 복잡한 것을 추가하면 :
public SomeComplexReturnValue Calculate(int i, float f, string s, object o)
{
// do work here
}
될 것입니다 :
public class SomeComplexInputForCalculation
{
public int i;
public float f;
public string s;
public object o;
}
public SomeComplexReturnValue Calculate(SomeComplexInputForCalculation input)
{
// do work here
}
도움이 되었기를 바랍니다...
"중요한 것"이 전부를 의미하는 것은 아닙니다. 몇 가지 규칙이 있습니다.
호출 객체 (보통 이름이 sender)를 전달하면 먼저 진행됩니다.
목록에는 약간의 유창함 이 있어야 합니다. 즉, 읽을 때 논증이 무엇인지 알아야합니다. 예:
CopyFolder (문자열 경로, 부울 재귀);
재귀를 먼저 넣으면 아직 컨텍스트가 없기 때문에 혼란 스러울 것입니다. 이미 폴더 (2), 폴더 (2)를 복사하는 것이라면 인수 재귀가 의미가 있습니다.
또한 IntelliSense와 유사한 기능이 제대로 작동합니다. 사용자는 인수를 채울 때 배우고 방법과 그 기능을 이해합니다. 마찬가지로 과부하는 동일한 부품에 대해 동일한 순서를 유지해야합니다.
그러면이 점에서 "동일한"인수가 여전히있을 수 있으며 순서가 인수의 유형에 따라달라고 할 수도 있습니다. 단지 몇 줄의 문자열을 연속으로 가지고 있고 나서 몇 개의 부울을 더 좋아 보이기 때문입니다. 어떤 수준에서 이것은 기술이 아닌 예술이 될 것입니다.
단일 인수로 끝나기 위해 모든 인수를 객체로 래핑해야한다는 진술은별로 신경 쓰지 않습니다. 그것은 단지 자신을 속이는 것입니다 (이 방법을 덜 복잡하게 만들지는 않지만 여전히 모든 인수가 있으므로 숨겨 두었습니다). 메소드에서 메소드로 몇 번 전달하면 리팩토링이 훨씬 쉬워 지지만 디자인 측면에서 차이를 만드는 척하는 것은 여전히 편리합니다. 그것은 당신이 무언가를 나타내는 의미있는 객체로 끝나는 것과는 다릅니다. 그것은 메소드 선언의 목록과 다르지 않은 많은 인수 일뿐입니다. 밥 삼촌을 행복하게 만들지는 않을 것입니다.
MessageBox.Show
있습니다. 이것도 살펴보십시오.