제목에 명시된 바와 같이 C #에서 사용되는 것과 같은 선택적 매개 변수 가 응용 프로그램 유지 관리에 방해가되거나 코드를 이해하기 어렵게 만들면 피해야합니까?
제목에 명시된 바와 같이 C #에서 사용되는 것과 같은 선택적 매개 변수 가 응용 프로그램 유지 관리에 방해가되거나 코드를 이해하기 어렵게 만들면 피해야합니까?
답변:
선택적 매개 변수는 내 경험상 좋은 것입니다. 나는 항상 기본값을 얻고 무엇을 호출하는지 알 수 있기 때문에 혼란스럽지 않습니다 (적어도 실제 기능보다 더 혼란스럽지 않습니다).
그것들에 대한 한 가지 사용은 이미 일반적으로 사용되거나 적어도 공용 인터페이스에있는 함수에 다른 매개 변수를 추가해야 할 때입니다. 그것들이 없으면, 나는 또 다른 인수를 가진 함수를 호출하기 위해 원래 함수를 다시 실행해야 할 것이며, 인수를 두 번 이상 추가하면 실제로 오래 될 수 있습니다.
new Circle(size, color, filled, ellipseProportions)
어디에 size
, color
필요하고 나머지는 기본값과 같은 인수를 추가하는 오버로드 된 메소드에 유용 합니다.
일반적으로 많은 / 선택적 매개 변수가 자주 필요한 경우 함수가 너무 많은 작업을 수행하므로 분할해야합니다. SRP (Single Responsibility Principle)를 위반했을 가능성이 있습니다.
그룹화 할 수있는 매개 변수를 찾으십시오 (예 : (x 및 y, 점이 됨).
이 선택적 매개 변수는 기본값으로 플래그입니까? 플래그를 사용하는 경우 함수가 분할되어야합니다.
즉, 선택적 매개 변수가 없어야한다는 말은 아니지만 일반적으로 하나 이상의 매개 변수가 코드 냄새를 나타냅니다.
또한 선택적 매개 변수가 속성으로 변경되고 생성자의 필수 매개 변수 부분이있는 함수가 실제로 클래스 여야한다는 단서가 될 수 있습니다.
선택적 매개 변수는 괜찮습니다.
일반적으로 정당화는 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
}
결과적으로 제공된 스펙을 매개 변수 오브젝트로 사용하여 팩토리 패턴을 기반으로 더 나은 디자인을 만들 수 있습니다.
코드가 수행하는 작업에 따라 다릅니다. 합리적인 기본값이있는 경우 선택적 매개 변수를 사용해야하지만 합리적인 기본값이없는 경우 선택적 매개 변수를 추가하면 코드가 더 복잡해집니다. 많은 경우 선택적 매개 변수는 nil 검사를 회피하고 분기 논리를 제거하는 깔끔한 방법입니다. Javascript에는 선택적 매개 변수가 없지만 ||로 매개 변수를 에뮬레이트하는 방법이 있습니다. (논리적 또는) 데이터베이스 관련 작업을 수행 할 때 항상 사용합니다. 사용자가 값을 제공하지 않으면 ||의 도움으로 내 값을 대체하기 때문입니다. 그러면 if 문 전체를 작성하는 번거 로움을 덜어줍니다.
선택적 매개 변수는 단순한 것을 단순하고 복잡한 것을 동시에 가능하게하는 좋은 방법입니다. 대부분의 사용자가 적어도 빠르고 더러운 사용 사례에서 원하는 합리적인 기본값이 있다면, 사용자가 함수를 호출 할 때마다 수동으로 지정하기 위해 상용구를 작성할 필요가 없습니다. 반면에, 사람들이 그것을 바꾸고 싶은 이유가 있다면, 그것을 노출시켜야합니다.
클래스를 사용하는 것은 장황하고 비효율적이며 클래스의 일반적인 정신 모델과 일치하지 않기 때문에 IMHO는 끔찍한 솔루션입니다. 함수는 동사에 대한 완벽한 추상화입니다. 즉, 무언가를하고 돌아 오는 것입니다. 클래스는 명사, 즉 상태가 있고 여러 가지 방법으로 조작 할 수있는 명사에 대한 올바른 추상화입니다. 전자가 API 사용자의 멘탈 모델이어야한다면 클래스로 만들지 마십시오.
나는 처음에 파이썬 에서이 기능을 좋아했으며 이미 사용한 메소드를 '확장'하는 데 사용했습니다. 그리고 그것은 멋지고 쉬워 보였지만 곧 다시 돌아 왔습니다. 선택적 매개 변수를 추가하면 이전 클라이언트가 의존했던 기존 방법의 동작을 기존 단위 테스트 사례에서 포착하지 않은 방식으로 수정했기 때문입니다. 기본적으로이를 수행하는 것은 공개 폐쇄 원칙을 위반하는 것입니다. 코드는 확장을 위해 열려 있지만 수정을 위해 닫힙니다. 따라서 기존 코드를 수정하기 위해이 기능을 사용하는 것은 좋지 않습니다. 하지만 처음부터 사용하면 괜찮아
선택적 매개 변수를 사용하는 것보다 다른 서명 (예 : 매개 변수)으로 함수를 오버로드하는 것이 더 좋을 것이라고 생각합니다.