반환 값에 더 나은 구문은 무엇입니까?
-
02-07-2019 - |
문제
나는 대규모 코드 검토를 해왔고 한 가지 패턴은 다음과 같습니다.
public bool MethodName()
{
bool returnValue = false;
if (expression)
{
// do something
returnValue = MethodCall();
}
else
{
// do something else
returnValue = Expression;
}
return returnValue;
}
이것은 내가 이것을 한 방법이 아닙니다. 나는 그것이 무엇인지 알았을 때 방금 가치를 반환했을 것입니다. 이 두 패턴 중 어느 것이 더 정확합니까?
나는 논리가 항상 하나의 상자로만 할당되도록 논리가 구성된 것처럼 보이고 지정된 후에는 코드가 실행되지 않도록 강조합니다.
해결책
이 주제에 대한 긴 토론이 있습니다 여기.
다른 팁
많은 사람들이 방법에서 한 번만 출구 지점을 갖는 것이 좋습니다. 위에서 설명한 패턴은 그 권장 사항을 따릅니다.
그 권장 사항의 주요 요지는 OU가 메소드에서 돌아 오기 전에 일부 메모리 나 상태를 정리해야한다면 해당 코드를 한 곳에만 사용하는 것이 좋습니다. 여러 종료 지점을 갖는 것은 종료 지점 중 하나 이상에서 정리 코드가 누락되어 정리 코드의 복제 또는 잠재적 문제로 이어집니다.
물론, 방법의 길이가 몇 줄이나 정리가 필요하지 않으면 여러 번의 반환이있을 수 있습니다.
제어 구조를 줄이기 위해 Ternary를 사용했을 것입니다 ...
return expression ? MethodCall() : Expression;
나는 소수에있을 것이라고 생각하지만 예제에 제시된 스타일이 마음에 듭니다. 로그 문을 추가하고 브레이크 포인트 인 IMO를 쉽게 설정하는 것은 쉽습니다. 또한 일관된 방식으로 사용하면 여러 리턴을하는 것보다 "패턴 일치"가 더 쉬워 보입니다.
그러나 이것에 대한 "올바른"대답이 있는지 확실하지 않습니다.
일부 학습 기관과 책은 단일 반환 관행을 옹호합니다.
더 좋든 아니든 주관적이든.
그것은 나쁜 OOP 디자인의 일부처럼 보입니다. 아마도 단일 방법의 내부보다 높은 수준에서 리팩토링되어야 할 것입니다.
그렇지 않으면, 나는 다음과 같이 3 배의 연산자를 사용하는 것을 선호합니다.
return expression ? MethodCall() : Expression;
짧고 읽기 쉬운다.
이러한 상황에서 방법에서 즉시 반환하십시오.
- 경계 조건을 찾았으며 고유 또는 센티넬 값을 반환해야합니다.
if (node.next = null) return NO_VALUE_FOUND;
- 필요한 값/상태는 False이므로 나머지 방법은 적용되지 않습니다 (일명 가드 조항). 예 :
if (listeners == null) return null;
- 이 방법의 목적은 특정 값을 찾고 반환하는 것입니다.
if (nodes[i].value == searchValue) return i;
- 방법의 다른 곳에서는 사용되지 않는 메소드에서 고유 한 값을 반환하는 조항에 있습니다.
if (userNameFromDb.equals(SUPER_USER)) return getSuperUserAccount();
그렇지 않으면 디버그 로깅, 리소스 정리 및 논리를 따르는 것이 더 쉬워 지도록 하나의 리턴 명령문 만 있으면 유용합니다. 위의 4 가지 사례를 먼저 처리하려고합니다. 신청하면 이름이 지정된 변수를 선언합니다. result(s)
가능한 빨리 늦고 필요에 따라 값을 할당하십시오.
그들은 둘 다 같은 작업을 수행합니다. 어떤 사람들은 메소드에는 하나의 항목과 하나의 종료 지점 만 있어야한다고 말합니다.
나도 이것을 사용합니다. 아이디어는 프로그램의 정상적인 흐름에서 자원이 해제 될 수 있다는 것입니다. 20 개의 다른 장소에서 방법을 뛰어 넘고 전에 Cleanup ()을 호출 해야하는 경우 또 다른 정리 방법을 20 번 추가해야합니다 (또는 모든 것을 리팩터).
코더가 메소드의 맨 위에 객체를 정의하는 설계를 취한 것 같아요 (예 : 목록u003CFoo> Toreturn = New Arraylistu003CFoo> ();) 그런 다음 메소드 호출 중에 채워지고 어떻게 든 부울 리턴 유형에 적용하기로 결정했습니다.
또한 메소드 본문의 중간에 반환 할 수 없다고 말하는 코딩 표준의 부작용 일 수도 있습니다.
반환 값이 할당 된 후에도 실행되지 않더라도 일부 코드는 나중에 추가 할 필요가 없다는 것을 의미하지는 않습니다.
사용될 수있는 가장 작은 코드는 아니지만 매우 리팩토링 친화적입니다.
Delphi는 함수의 리턴 유형 인 "결과"라는 변수를 자동으로 생성 하여이 패턴을 강제합니다. 함수가 종료 될 때 "결과"가 무엇이든간에 반환 값이됩니다. 따라서 "반환"키워드는 전혀 없습니다.
function MethodName : boolean;
begin
Result := False;
if Expression then begin
//do something
Result := MethodCall;
end
else begin
//do something else
Result := Expression;
end;
//possibly more code
end;
사용 된 패턴은 Verbose입니다. 그러나 레지스터 창을 열고 EAX를 점검하지 않고 반환 값을 알고 싶다면 디버깅하기가 더 쉽습니다.