선택적 매개 변수가 응용 프로그램 유지 관리에 도움이되거나 방해가됩니까? [닫은]


15

제목에 명시된 바와 같이 C #에서 사용되는 것과 같은 선택적 매개 변수 가 응용 프로그램 유지 관리에 방해가되거나 코드를 이해하기 어렵게 만들면 피해야합니까?


3
면책 조항 : 잘못된 손에 든 언어 기능은 남용 될 수 있습니다. 언어가 이것을 현명한 방법으로 구현하고이 언어 기능이 기존 언어 기능과 너무 겹치지 않으면 실제로는 매우 유용합니다. 파이썬은 깔끔한 param Packing / unpacking과 다른 파라미터 "tricks"(Perl 의미가 아닌 좋은 평가)를 가지고 있습니다.
Job

선택적 매개 변수를 사용하지 않고 Excel과 인터페이스하는 앱을 C #으로 작성하십시오. 그것은 의심의 여지없이 당신의 질문에 대답해야합니다.
Dunk

답변:


22

선택적 매개 변수는 내 경험상 좋은 것입니다. 나는 항상 기본값을 얻고 무엇을 호출하는지 알 수 있기 때문에 혼란스럽지 않습니다 (적어도 실제 기능보다 더 혼란스럽지 않습니다).

그것들에 대한 한 가지 사용은 이미 일반적으로 사용되거나 적어도 공용 인터페이스에있는 함수에 다른 매개 변수를 추가해야 할 때입니다. 그것들이 없으면, 나는 또 다른 인수를 가진 함수를 호출하기 위해 원래 함수를 다시 실행해야 할 것이며, 인수를 두 번 이상 추가하면 실제로 오래 될 수 있습니다.


1
+1 그리고 new Circle(size, color, filled, ellipseProportions)어디에 size, color필요하고 나머지는 기본값과 같은 인수를 추가하는 오버로드 된 메소드에 유용 합니다.
Michael K

15

일반적으로 많은 / 선택적 매개 변수가 자주 필요한 경우 함수가 너무 많은 작업을 수행하므로 분할해야합니다. SRP (Single Responsibility Principle)를 위반했을 가능성이 있습니다.

그룹화 할 수있는 매개 변수를 찾으십시오 (예 : (x 및 y, 점이 됨).

이 선택적 매개 변수는 기본값으로 플래그입니까? 플래그를 사용하는 경우 함수가 분할되어야합니다.

즉, 선택적 매개 변수가 없어야한다는 말은 아니지만 일반적으로 하나 이상의 매개 변수가 코드 냄새를 나타냅니다.

또한 선택적 매개 변수가 속성으로 변경되고 생성자의 필수 매개 변수 부분이있는 함수가 실제로 클래스 여야한다는 단서가 될 수 있습니다.


1
조심해서 +1 아무리 좋은 기능이라도 남용 될 수 있습니다.
Michael K

3
이는 API 사용자가 가장 간단한 작업을 수행하기 위해 최소한 6 개의 클래스와 15 개의 함수를 사용해야하는 과도한 엔지니어링 라비올리 코드 생성에 대한 훌륭한 조언입니다.
dsimcha

1
@ dsimcha, 내가 쓴 것에서 어떻게 얻습니까? 와. 설명 해주십시오? 선택적인 매개 변수가 많을 때 얻을 수있는 "슈퍼 기능"을 갖는 것은 똑같이 나쁜 디자인입니다. SOLID 설계 원칙과 테스트 가능한 코드 작성에 대해 읽으십시오. TDD를 사용하는 것이 좋습니다. 그런 다음 다시 돌아와서 함수의 매개 변수를 줄이는 것이 좋지 않다고 설명하십시오.
CaffGeek

1
테스트 가능한 코드는 훌륭하지만 지나치게 세분화되거나 장황하지 않고 함수가 적절한 추상화 상태에 클래스를 포함시키지 않는 깨끗하고 사용 가능한 API도 있습니다. 나는 높은 수준의 추상화로 정의 된 책임을 가진 단일 책임 원칙을 믿습니다. 책임이 너무 낮은 수준으로 정의되면 개별 단위가 지나치게 단순화되어 상호 작용이 지나치게 복잡해집니다.
dsimcha

1
@ dsimcha, 요점을 놓치고 있습니다. 개별 단위는 개별 단위로 유지되어야하며 단일 기능으로 함께 묶이지 않아야합니다. 그렇다고 그들이 모두 공개적으로 접근 가능한 기능이라는 의미는 아닙니다. API는 코드의 관문이며 깨끗하고 간결해야합니다. 여러 선택적 매개 변수가있는 기능은 깨끗하지도 간결하지도 않습니다. 그러나 논리 매개 변수로 단일 함수를 오버로드하는 것이 훨씬 명확합니다. 예를 들어, 많은 API에는 두 개의 매개 변수가 선택적이지만 하나 또는 다른 것이 필요한 함수가 있습니다. 둘 다 선택 사항으로 표시 될 때 분명한 것은 무엇입니까?
CaffGeek

4

선택적 매개 변수는 괜찮습니다.

일반적으로 정당화는 a) 메소드에 대해 가능한 많은 인수가 있다는 것을 알고 있지만 API를 혼란스럽게 할까봐 과부하하지 않으려는 경우 또는 b) 가능한 모든 인수를 모르는 경우 사용자에게 강제로 배열을 제공하고 싶지 않습니다. 각각의 경우에 선택적 파라미터는 깔끔하고 우아한 방식으로 구출됩니다.

여기 몇 가지 예가 있어요.

1. 오버로드를 피하고 배열을 지정하고 싶지 않습니다

C, Perl, Java 등에서 printf () 를 살펴보십시오 . 선택적 매개 변수의 강력한 예입니다.

예를 들면 다음과 같습니다.

printf("I want %d %s %s",1,"chocolate","biccies");

printf("I want %d banana",1);

오버로드, 배열 없음, 간단하고 직관적 임 (표준 문자열 형식 코드를 파악한 후) 일부 IDE는 형식 문자열이 선택적 매개 변수와 일치하지 않는지 알려줍니다.

2. 기본값 사용을 허용하고 메소드의 사용자에게 숨겨져 있어야합니다.

sendEmail ( "test@example.org");

sendEmail 메소드는 다양한 필수 값이 누락되었음을 감지하고 정의 된 기본값 (제목, 본문, cc, 숨은 참조 등)을 사용하여 채 웁니다. API는 깨끗하면서도 유연하게 유지됩니다.

너무 많은 매개 변수에 대한 참고 사항

그러나 다른 사람들이 언급했듯이 메서드에 필수 매개 변수 가 너무 많으면 디자인에 문제가 있음을 나타냅니다. 런타임시 이상한 결과를 초래하여 실수로 개발자가 전환 할 수 있으므로 동일한 유형을 공유하는 경우 특히 그렇습니다.

String myMethod(String x, String y, String z, String a, int b, String c, int d) {}

Introduce Parameter Object 리팩토링을 위한 이상적인 후보입니다.

String myMethod(ParameterObject po) {}

class ParameterObject {
  // Left as public for clarity
  public String x;
  public String y;
  ... etc

}

결과적으로 제공된 스펙을 매개 변수 오브젝트로 사용하여 팩토리 패턴을 기반으로 더 나은 디자인을 만들 수 있습니다.


1
printf와 같은 문자열 형식 지정 함수는 규칙에 대한 예외 입니다. 옵션 매개 변수 의 무제한 목록을 사용하는 동안 인수가 구현 방법에도 불구하고 선택적 매개 변수보다 배열과 비슷 하다고 주장 할 수 있습니다 .
CaffGeek

@ 차드 (선택 사항)와 매개 변수가 코드 냄새로 전환 될 때 (응답에서 언급했듯이)를 더 잘 구별하도록 답변을 조정했습니다.
게리 로우

@Gary Rowe, 너무 많은 선택적 매개 변수는 대부분의 경우에도 좋지 않습니다.
CaffGeek

@Chad 나는 동의하지만 대부분의 언어는 선택적 인수의 수를 제한하는 방법을 제공하지 않으므로 전혀 또는 전혀 접근하지 않습니다. 당신은 그것을 강제하기 위해 메소드에 맡겨야하며 분명히 메소드가 500 개의 변수를 다루는 경우 분명히 리팩터링해야합니다.
게리 로우

@Gary Rowe, "대부분의 언어는 선택적 인수의 수를 제한하는 방법을 제공하지 않습니다"는 무엇을 의미합니까? 대부분의 언어에서는이를 표시하거나 함수를 호출 할 때 값을 제공하지 않지만 함수 헤더에는 여전히 매개 변수가 정의되어 있습니다. 물론 일부 언어에서는 정의 된 매개 변수를 채운 후 원하는 수의 매개 변수를 추가 할 수 있지만 여기서는이 매개 변수가 선택적 매개 변수라고 생각하지 않습니다. (문자열 형식 예외 제외)
CaffGeek

2

C #의 기본 매개 변수에 대한 문제 중 하나는 void DoSomething (int x = 1) 생각합니다. 상수입니다. 즉, 기본값을 변경하면 해당 메소드 호출의 소비자를 다시 컴파일해야합니다. 이것이 쉬운 일이지만 이것이 위험한 경우가 있습니다.


1

코드가 수행하는 작업에 따라 다릅니다. 합리적인 기본값이있는 경우 선택적 매개 변수를 사용해야하지만 합리적인 기본값이없는 경우 선택적 매개 변수를 추가하면 코드가 더 복잡해집니다. 많은 경우 선택적 매개 변수는 nil 검사를 회피하고 분기 논리를 제거하는 깔끔한 방법입니다. Javascript에는 선택적 매개 변수가 없지만 ||로 매개 변수를 에뮬레이트하는 방법이 있습니다. (논리적 또는) 데이터베이스 관련 작업을 수행 할 때 항상 사용합니다. 사용자가 값을 제공하지 않으면 ||의 도움으로 내 값을 대체하기 때문입니다. 그러면 if 문 전체를 작성하는 번거 로움을 덜어줍니다.


1

선택적 매개 변수는 단순한 것을 단순하고 복잡한 것을 동시에 가능하게하는 좋은 방법입니다. 대부분의 사용자가 적어도 빠르고 더러운 사용 사례에서 원하는 합리적인 기본값이 있다면, 사용자가 함수를 호출 할 때마다 수동으로 지정하기 위해 상용구를 작성할 필요가 없습니다. 반면에, 사람들이 그것을 바꾸고 싶은 이유가 있다면, 그것을 노출시켜야합니다.

클래스를 사용하는 것은 장황하고 비효율적이며 클래스의 일반적인 정신 모델과 일치하지 않기 때문에 IMHO는 끔찍한 솔루션입니다. 함수는 동사에 대한 완벽한 추상화입니다. 즉, 무언가를하고 돌아 오는 것입니다. 클래스는 명사, 즉 상태가 있고 여러 가지 방법으로 조작 할 수있는 명사에 대한 올바른 추상화입니다. 전자가 API 사용자의 멘탈 모델이어야한다면 클래스로 만들지 마십시오.


1

선택적 인수의 문제점은 사람들이 관련 코드를 새로운 함수로 추출하는 대신 함수에 대한 점점 더 많은 인수를 사용하는 경향이 있다는 것입니다. 이것은 php 에서 극단으로 가져옵니다 . 예를 들어 :

bool array_multisort ( array &$arr [, mixed $arg = SORT_ASC
                      [, mixed $arg = SORT_REGULAR [, mixed $... ]]] )

1

선택적 매개 변수는 기본적으로 함수를 오버로드하는 다른 방법입니다. 그래서 이것은 기본적으로 "기능 과부하가 나쁜가?"


1

나는 처음에 파이썬 에서이 기능을 좋아했으며 이미 사용한 메소드를 '확장'하는 데 사용했습니다. 그리고 그것은 멋지고 쉬워 보였지만 곧 다시 돌아 왔습니다. 선택적 매개 변수를 추가하면 이전 클라이언트가 의존했던 기존 방법의 동작을 기존 단위 테스트 사례에서 포착하지 않은 방식으로 수정했기 때문입니다. 기본적으로이를 수행하는 것은 공개 폐쇄 원칙을 위반하는 것입니다. 코드는 확장을 위해 열려 있지만 수정을 위해 닫힙니다. 따라서 기존 코드를 수정하기 위해이 기능을 사용하는 것은 좋지 않습니다. 하지만 처음부터 사용하면 괜찮아


0

선택적 매개 변수를 사용하는 것보다 다른 서명 (예 : 매개 변수)으로 함수를 오버로드하는 것이 더 좋을 것이라고 생각합니다.


왜? 모든 메소드가 동일한 기본 기능을 가진 경우 기본 매개 변수를 사용하여 오버로드 된 메소드를 하나의 메소드로 결합 할 수 있다면 더 깨끗하다고 ​​생각합니다.
Amit Wadhwa

당신은 그렇게 생각할 수 있습니다. Microsoft가 모든 것을 올바르게 수행한다고 생각하는 사람은 아니지만 .NET 프레임 워크를 사용할 때 과부하가 발생하지 않습니다 .OL VB6에서와 같이 하나의 거대한 함수 서명이 있습니다.
HardCode
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.