문제

저는 이 접근 방식을 옹호하지 않는다는 점부터 말씀드리고 싶습니다. 하지만 최근에 이를 보고 유죄를 선고하는 데 사용할 수 있는 이름이 있는지 궁금합니다.자, 여기 갑니다.

이제 메서드가 있고 값을 반환하려고 합니다.너 또한 오류 코드를 반환하고 싶습니다.물론 예외가 훨씬 더 나은 선택이지만 어떤 이유로든 대신 오류 코드가 필요합니다.기억하세요, 저는 여기서 악마의 옹호자 역할을 하고 있습니다.따라서 다음과 같이 일반 클래스를 만듭니다.

class FunctionResult<T>
{
    public T payload;
    public int result;
}

그런 다음 다음과 같이 함수를 선언하십시오.

FunctionResult<string> MyFunction()
{
    FunctionResult<string> result;
    //...

    return result;
}

이 패턴의 한 가지 변형은 문자열 대신 오류 코드에 열거형을 사용하는 것입니다.이제 내 질문으로 돌아갑니다.이것에 대한 이름이 있나요? 그렇다면 무엇인가요?

도움이 되었습니까?

해결책

나는 이것이 특별히 반패턴이 아니라는 데 동의합니다.사용방법에 따라 냄새가 날 수도 있습니다.실제로 예외를 사용하고 싶지 않은 이유가 있습니다(예:반환되는 오류는 우선 '예외'가 아닙니다.

서비스가 오류와 올바른 값을 모두 포함하여 결과에 대해 공통 모델을 반환하도록 하려는 경우가 있습니다.이는 결과를 예외 또는 기타 오류 구조로 변환하는 낮은 수준의 서비스 상호 작용으로 래핑될 수 있지만 서비스 수준에서는 서비스가 예외 구조를 정의하지 않고도 결과와 상태 코드를 반환할 수 있습니다. 먼 경계를 넘어 번역되어야 합니다.

이 코드는 반드시 오류가 아닐 수도 있습니다.응답 본문과 함께 상태 코드를 포함한 다양한 데이터로 구성된 HTTP 응답을 생각해 보세요.

다른 팁

글쎄요 ~ 아니다 반패턴.C++ 표준 라이브러리는 이 기능을 사용하며 .NET은 특별한 기능도 제공합니다. FunctionResult .NET 프레임워크의 클래스입니다.그것은 ~라고 불린다 Nullable.예, 이것은 함수 결과에만 국한되지 않지만 그러한 경우에 사용될 수 있으며 실제로 여기에서 매우 유용합니다..NET 1.0에 이미 Nullable 수업을 위해 확실히 사용되었을 것입니다. NumberType.TryParse 메서드 대신 out 매개변수.

나는 일반적으로 페이로드를 (const가 아닌) 참조로 전달하고 오류 코드를 반환 값으로 전달합니다.

나는 게임 개발자이므로 예외를 금지합니다.

Konrad의 말이 맞습니다. C#은 항상 이중 반환 값을 사용합니다.하지만 저는 TryParse, Dictionary.TryGetValue 등을 좋아합니다.C#의 메소드.

int value;
if (int.TryParse("123", out value)) {
    // use value
}

대신에

int? value = int.TryParse("123");
if (value != null) {
    // use value
}

...주로 Nullable 패턴은 값이 아닌 반환 유형(예: 클래스 인스턴스)으로 확장되지 않기 때문입니다.Dictionary.TryGetValue()에서는 작동하지 않습니다.그리고 TryGetValue는 KeyNotFoundException(디버거에서 지속적으로 "첫 번째 예외"가 발생하지 않음, 틀림없이 더 효율적임)보다 좋고, null을 반환하는 get()의 Java 관행(널 값이 예상되는 경우)보다 좋으며, 먼저 ContainsKey()를 호출하세요.

하지만 이것은 ~이다 여전히 약간 까다롭습니다. C#처럼 보이기 때문에 out 매개변수를 사용해야 합니다.클래스를 인스턴스화하면 모든 효율성 향상이 손실될 수 있습니다.

("문자열" 유형이 소문자인 것을 제외하면 Java일 수 있습니다.물론 Java에서는 이중 반환 값을 에뮬레이션하려면 클래스를 사용해야 합니다.)

이것이 안티 패턴인지 확실하지 않습니다.나는 성능상의 이유로 또는 아마도 메소드가 실패할 수 있다는 사실을 더 명확하게 하기 위해 예외 대신에 이것이 사용되는 것을 흔히 보았습니다.나에게는 안티 패턴이라기보다는 개인적인 취향인 것 같다.

나는 이것이 안티 패턴이 아니라고 말하는 사람들의 의견에 동의합니다.특정 상황에서는 완벽하게 유효한 패턴입니다.다음은 예외입니다. 특별한 상황에서는 예상되는 상황에서 반환 값(예제와 같은)을 사용해야 합니다.일부 도메인은 클래스의 유효한 결과와 잘못된 결과를 기대하며 둘 중 어느 것도 예외로 모델링되어서는 안 됩니다.

예를 들어, X량의 휘발유가 주어지면 자동차가 A에서 B까지 이동할 수 있습니까? 그렇다면 남은 휘발유는 얼마나 됩니까?이러한 종류의 질문은 귀하가 제공한 데이터 구조에 이상적입니다.A에서 B로 이동할 수 없는 것이 예상되므로 예외를 사용해서는 안 됩니다.

이 접근 방식은 실제로 제가 본 다른 접근 방식보다 훨씬 낫습니다.예를 들어, C의 일부 함수는 오류가 발생하면 반환되고 성공한 것처럼 보입니다.실패했음을 알 수 있는 유일한 방법은 최신 오류를 가져오는 함수를 호출하는 것입니다.

나는 sem_init가 OSX에서 작동하지 않는다는 것을 마침내 발견하기 전에 내 MacBook에서 세마포어 코드를 디버깅하려고 몇 시간을 보냈습니다!오류 없이 컴파일되었고 오류 없이 실행되었습니다. 그러나 세마포어는 작동하지 않았고 그 이유를 알 수 없었습니다.나는 다음을 사용하는 응용 프로그램을 포팅하는 사람들을 불쌍히 생각합니다. POSIX 세마포어 OSX로 전환하고 이미 디버깅된 리소스 경합 문제를 처리해야 합니다.

"이것이 오류인지 아닌지 결정할 수 없습니다" 패턴은 어떻습니까?실제로 예외가 발생했지만 부분적인 결과를 반환하려는 경우 결과를 예외에 래핑하면 됩니다.

예외를 사용하고 싶지 않은 경우 가장 깔끔한 방법은 함수가 오류/성공 코드를 반환하고 결과로 채워지는 참조 또는 포인터 인수를 취하도록 하는 것입니다.

나는 그것을 안티 패턴이라고 부르지 않을 것입니다.이는 예외를 사용하는 것보다 종종 선호되는 매우 잘 입증된 실행 가능한 방법입니다.

메서드가 가끔 실패할 것으로 예상되지만 예외적인 것으로 간주하지 않는 경우 .NET Framework에서 사용되는 다음 패턴을 선호합니다.

bool TryMyFunction(out FunctionResult result){    

     //...    
     result = new FunctionResult();
}

냄새와 반대 패턴에 대한 논쟁을 보면 섬 밖에서 서로 투표하려고 하는 다양한 프로그래밍 구조가 있는 "Survivor" TV 쇼가 생각납니다.나는 무엇을 해야 하고 하지 말아야 하는지에 대한 지속적으로 발전하는 칙령 목록보다는 "construct X에는 이런저런 장단점이 있습니다"를 보는 것을 선호합니다.

안티패턴 지정을 방어하기 위해 이 코드는 다음과 같은 몇 가지 방법으로 사용됩니다.

  1. 개체 x = MyFunction().payload; (반환 결과 무시 - 매우 나쁨)
  2. 정수 코드 = MyFunction().result; (페이로드 버리기 - 의도한 용도라면 괜찮을 수도 있습니다.)
  3. FunctionResult x = MyFunction();//... (여러 곳에서 이를 확인하기 위한 추가 FunctionResult 개체와 추가 코드)

반환 코드를 사용해야 한다면 괜찮습니다.그러나 반환 코드를 사용하십시오.추가 페이로드를 포함하려고 하지 마세요.그게 다야 심판 그리고 밖으로 매개변수(C#)는 다음과 같습니다.Nullable 유형은 예외일 수 있지만 이를 지원하기 위해 언어에 추가 설탕이 구워졌기 때문입니다.

여전히 이 평가에 동의하지 않는 경우 이 답변(전체 질문이 아님)에 반대 투표를 하세요.그것이 안티 패턴이라고 생각한다면 찬성 투표하세요.우리는 이 답변을 사용하여 커뮤니티가 어떻게 생각하는지 살펴보겠습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top