2012-03-16 6 views
5

유창한 인터페이스를 작성하기 시작한 Martin Fowler는 유창한 인터페이스 (나는 Eric Evans가 그 용어를 만들었다는 사실을 깨닫지 못했다.)에 대해 썼다. 이 기사에서 Martin은 setter가 일반적으로 구성 또는 작업중인 개체의 인스턴스를 반환한다고 말하면서 그는 CQS를 위반한다고 말합니다.유창한 인터페이스가 명령 쿼리 분리 원칙을 위반합니까?

중괄호 세계에서 일반적인 규칙은 CommandQuerySeparation의 원리를 따르기 때문에 내가 좋아하는 방법이 무효가 수정이다. 이 컨벤션은 유창한 인터페이스 인 을 방해하므로이 사례에 대한 컨벤션을 중지 할 의향이 있습니다.

그래서 같은 내 유창 인터페이스 않는 경우

myObject 
    .useRepository("Stuff") 
    .withTransactionSupport() 
    .retries(3) 
    .logWarnings() 
    .logErrors(); 

는 CQS이 진정으로 위반인가?

업데이트 로깅 경고 및 오류가 별도의 동작으로 표시되도록 예제를 만들었습니다.

+0

'logWarningsAndErrors'는 무엇을 반환합니까? 그렇지 않다면 정말로 유창한 인터페이스입니까? –

+0

@ M.Babcock이 샘플을 업데이트했습니다. 물론,'logWarningsAndErrors'는 추가 동작을 추가 할 수있는 인터페이스를 반환합니다. –

답변

0

아니요. 여기 패턴은 "구성"입니다. 이러한 구성 명령은 구성 개체 자체를 명령과 무관 한 무언가와 반대로 반환합니다. 구성 목적에 도움이되는 명령이 관련이없는 데이터를 반환하면 명령/쿼리 분리 문제가 발생합니다. 예를 들면 다음과 같습니다.

if (myObject.UseRepository("Stuff") > 1 && myObject.UseRepository("Bla") < 5) { 
    // oh, good, some invisible stuff internal to myObject is in right interval... 
} 
+2

sry, 나는 당신의 대답을 이해하지 못합니다. 그러나 나는하고 싶습니다. 확장 할 수 있습니까? "네가 가진다면 ..."어디 있었는지? 또한 스 니펫에 내부 상태가 변경되지 않습니다. 나는 "묻지 마라."원칙을 위반하는 것을 본다.하지만 그게 다다. –

+0

재차하려고 노력할 때, 아직도 이해하기 힘든 ... –

9

예, 그렇습니다. 이러한 모든 메소드는 분명히 무언가를 반환하고 분명히 부작용이 있습니다 (반환 값을 사용하지 않으면서도 호출 할 수 있음). CQS의 정의에서 돌연변이가가 가치를 반환하면 안되기 때문에 우리에게는 명백한 위반이 있습니다.

그러나 CQS가 위반되었다는 것이 중요합니까? 유창한 인터페이스로 모든 것을 고려하면 모든 것을 고려할 수 있으며 잘 알려진 장점과 단점이있는 잘 알려진 패턴이라고 생각하면 왜 으로해야합니까? 원칙 X를 위반하는 것이 중요합니까?

+0

'logWarningsAndErrors'가 어떤 것을 반환하는 것이 명백한가요? –

+0

@ M.Babcock : 엄밀히 말하면, 그 발췌 문장에서 나온 것이 아닙니다. 너 나 거기있어. – Jon

+0

동의합니다. 왜 당신이 그것을 사용하는 데 도움이된다면 그것은 제비꽃 원칙 X면 중요합니다. –

2

개체를 변경할 때이 원칙에 위배되지만 새 개체 만 반환하는 경우에는 위 원칙에 위배됩니다. myObject이 문 다음에 변경되지 않은 경우

var newObject = myObject 
    .useRepository("Stuff") 
    .withTransactionSupport() 
    .retries(3) 
    .logWarningsAndErrors(); 

은 모든 것이 OK입니다. 일반적으로 유창한 인터페이스는 부작용이있을 경우에만 CQS 원칙을 위반합니다.

그러나 예제가 쿼리를 전혀 나타내지 않는다면 문제가됩니다. "유창"이란 반드시 "검색어"를 의미합니까? 이것은 아마도 동일한 객체가 한 액션에서 다음 액션으로 전달되는 액션 - 유창한 인터페이스로 인식 될 수 있습니다.

+0

흠,하지만 구성의 전체 요점은 (구성에 따라) 개체를 변경하는 것입니다 그래서 왜 귀찮게? –

+0

수정할 개체가 새 인스턴스 또는 이전 인스턴스 인 경우 어떤 차이가 있습니까? 이 중 4 개의 호출 중 하나는 표현식의 반환 값을 수정하거나 (아무 것이나) 반환하지 않으므로 생략해야합니다. – Jon

+0

질문은 기존 개체를 수정하고 동시에 결과를 반환하면 명령과 쿼리를 동시에 작성하는 것입니다. 명령 ** 또는 ** 쿼리 여야합니다. –