"방법은 값을 반환하거나 부작용을 가져야하지만 둘다는 안된다"


12

나는 메소드가 반환 값을 가져야하고 (참조 적으로 투명해야 함) 부작용을 가져야하지만 둘다는 안된다는 것을 한 번 읽었습니다. 이 규칙에 대한 언급은 찾을 수 없지만 더 자세히 알고 싶습니다.

이 조언의 기원은 무엇입니까? 어떤 사람이나 공동체에서 발생 했습니까?

추가 크레딧 :이 조언을 따르면 어떤 이점이 있습니까?


1
@gnat 네, 주로 역사에 관한 것입니다. 나는 여분의 신용 부분이 너무 주관적이라고 생각하기 어려웠으며, 역사는 폐쇄를 피할 수있는 더 좋은 기회를 가졌다는 것을 두려워했습니다. 태그를 추가하겠습니다.
웨인 콘래드

이 답변 의 저자 가 주장한 혜택 이나 전혀 주장 할 수있는 모든 혜택 의 목록 에 대해 궁금한 점이 있습니까?
gnat

@gnat 필자는 저자가 주장한 이점 (다시 말해서 폐쇄를 두려워 함)에 대해 묻지 만, 실제로 질문하고 싶은 질문에 답하고 있다는 사실에 대해서는 신경 쓰지 않는다 . 질문에서 "고발 된"항목을 제거하여 주제에 대한 기적적인 답변을 만들면 질문이 너무 주관적으로 넘어 가게됩니까?
Wayne Conrad

"불필요한 이유"는 질문이 너무 광범위 하게 종결 될 가능성이 높습니다 . "개방형으로 유지하기"를 선호한다면 저자가 주장한 혜택을 위해 범위를 좁히는 것이 더 안전 할 것입니다.
gnat

한 가지 이점은 많은 양의 코드로 지불하면 추가 비용이 발생한다는 것입니다. "doSomething; GetResultOfSomething; HandleErrorsFromSomething;"
Ⴖ uі

답변:


13

Greg Young에 따르면이 아이디어는 Bertrand Meyer : Command-Query 분리에서 시작되었습니다 .

모든 메소드는 조치를 수행하는 명령이거나 호출자에게 데이터를 리턴하는 쿼리 여야하지만 둘다는 아니라고 명시합니다. 다시 말해, 질문을하면 대답이 바뀌지 않아야합니다 . 1 더 공식적으로, 메소드는 참조가 투명하고 부작용이없는 경우에만 값을 리턴해야합니다.

1 : 에펠 : 소프트웨어 엔지니어링 슬라이드 43-48 용 언어

도메인 기반 디자인에서 이는 Greg Young이 명명 한 CQRS (Command-Query-Read Separation / Segregation)와 유사합니다.

Greg Young은이 CQRS 기사 에서 Martin Fowler가 언급 한 것처럼 Bertrand의 CQS를 CQRS로 명명했습니다.

혜택

  • 읽기 (쿼리) 부분은 쓰기 (명령) 부분과 다르게 스케일 / 조정될 수 있습니다. 둘을 분리하면 최적화 / 성능이 핵심 일 때 서로 방해가되지 않습니다.

자세한 내용은 Martin Fowler 링크기사를 읽으십시오 .


1
당연히 많은 상황에서 유용한 결과를 생성 하고 동시에 일부 수정 수행하는 것이 두 가지를 별도로 수행하는 것보다 더 비싸지 않습니다.
중복 제거기

1
@Deduplicator InterlockedCompareExchange의 진부한 예?
Ⴖ uі

1
이 조언은 반환이 명령에서 수행 된 것에 대한 정보 일 때 적용되지 않지만 데이터 세트에서 행을 제거하는 방법은 데이터 세트 상태를 변경하고 주어진 기준에 따라 표시된 행을 제거 할 수 있습니다. 그런 다음 제거 된 행 수 또는 해당 행이있는 목록을 반환하십시오.
T. Sar

4

나는 그것이 어디에서 왔는지 모르지만 좋은 조언이며 이해하기가 매우 간단합니다.

깔끔하게 디자인 된 프로그램은 여러 부분으로 나뉘어 다양한 방식으로 결합되어 구성됩니다. 특정 부분이 무엇을하는지 추론하기가 어려울수록 프로그램이 예측 가능한 방식으로 반응하도록하는 것이 더 어려워집니다.

부작용을 일으키는 부품을 분리하면 나머지를 쉽게 추론, 테스트 및 디버그 할 수 있습니다. 부작용을 발생시키는 각 부품의 부작용 수를 줄이면 동일한 방식으로 해당 부품을보다 쉽게 ​​사용할 수 있습니다.

더 분해하면 반환 값이 적용됩니다. 부작용은 효과입니다. 함수는 입력과 효과의 수가 많을수록 실제로 수행하는 작업을 추론하기가 어렵 기 때문에 함수는 1 개의 효과 만 발생해야합니다 (가능한 경우).


이 질문에 대한 답변도 시도하지 않습니다. 답변 방법
gnat

@gnat 내 질문은 두 부분으로 나뉩니다 : 주요 질문 ( "누가")과 추가 크레딧 ( "이유") 이것은 추가 크레딧 부분을 다루지 않습니까?
Wayne Conrad

내가 읽은 내용 ( " 청구 된 이익")에 따라, 왜 부분은 견적 작성자가 제안한 것으로 예상됩니다. 질문은 가능한 모든 혜택 의 목록 을 요구하는 것으로 보이지 않습니다
gnat

2
@ gnat 나는이 조언을 뒷받침하는 이유와 그 맥락에 대한 이해를 돕기위한 시도로 질문을 이해했다. 질문의 일부만을 다루는 것이 부적절하다고 생각하지 않습니다.
Morgen

1

추가 크레딧 : 이 조언을 따를원래 주장 된 이점은 무엇입니까 ?

부작용에서 리턴 값을 분리하는 것의 장점 중 하나는 단락 평가 로 인해 발생할 수있는 잠재적 인 문제를 제거한다는 것 입니다.

bool FooWithSideEffect() {
    // do query
    // do side effect
    return resultOfQuery;
}

bool BarWithSideEffect() {
    // do query
    // do side effect
    return resultOfQuery;
}

void BadShortCircuitEvaluation()
{
    // the programmer's intent is to have side effects of both functions
    if (FooWithSideEffect() && BarWithSideEffect() ) {
        // do something
    }

    // in case FooWithSideEffect() returns true, 
    // then BarWithSideEffect() is not called at all
    // because of short-circuit evaluation
}

이것은 조언의 저자에 의해 주장 된 혜택 입니까?
gnat

@gnat 나는 역사와 실용이 혼재되어 있습니다.
Nick Alexeev

1
주석과 코드가 일치하지 않으면 FooWithSideEffects가 false
jk를
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.