2011-04-23 1 views
2

다음과 같은 상황이 너무 자주 일어나서 절대로 쉽게 지울 수 없습니다. 다른 사람들이 어떻게 처리하는지 묻고 싶습니다.()반복하지 않고 깨끗하고 집중적 인 자체 문서화 방법

if DemoOptionSpecified() { 
    timeout = ReadInDemoTimeout(); 
    DoDemoVersion(timeout); 
} else 
    DoRealVersion(); 

DemoOptionSpecified를 인수 문자열의 grep 일종의을 수행하고 true 또는 false를 반환 :

데모 = 60 명령 행 인수의 처리는 다음과 같이 수행 된 경우 상상해보십시오.

ReadInDemoTimeout()은 또한 일종의 grep, 동일한 문자열을 수행하고 정수를 반환합니다.

두 가지 넝마가 두 가지 일을하고 있지만 물론 두 가지를 수행하는 데 오직 하나의 grep 만 있으면됩니다. 하나가 아닌 두 개의 greps가 여기서는 중요하지 않지만 다른 시나리오에서는 두 개의 데이터베이스 또는 Ajax 호출이 사용됩니다.

DemoOptionSpecified()가 제공되는 것 외에는 아무것도하지 않는 것이 좋습니다. 값의 추가 캡처는 메서드 이름에 의해 제안되지 않습니다.

데모 옵션이없는 경우 ReadInDemoTimeout() 메서드를 false로 반환하는 대신에 옵션을 설정하면 시간 제한 값에 대해서만 듣기를 원합니다. DoRealVersion()은 제한 시간 값을 고려하지 않습니다.

여기에는 아무런 타협없는 깨끗한 코드 패턴이 없다고 느낍니다. 생각? 예를 들어 C++를 사용하여이 같은

답변

2

내가 어떤 문제가 표시되지 않습니다 모두 않는 방법 갖는 - 그냥 제대로 이름을이을 :

DemoOption demoOption = getDemoOption(); 
if (demoOption.wasSpecified()) { 
    int timeout = demoOption.getValue(); 
    doDemoVersion(timeout); 
} 
else { 
    doRealVersion(); 
} 

당신은 그것을 간단하게, 그리고 방법은 값을 반환, 또는 수 널 (null) 옵션이 설정되지 않은 경우 :

Integer demoTimeout = getDemoOptionIfSpecified(); 
if (demoTimeout != null) { 
    doDemoVersion(demoTimeout); 
} 
else { 
    doRealVersion(); 
} 

을 그리고 난 방법 범용 할 것 :

Integer demoTimeout = getOptionIfSpecified("demo", Integer.class); 
if (demoTimeout != null) { 
    doDemoVersion(demoTimeout); 
} 
else { 
    doRealVersion(); 
} 

나는 두 가지를하는 방법으로 보지 않습니다. 그것이하는 한 가지는 "하나가 있다면 옵션의 가치를 얻는 것"입니다. 그런 다음 결과에 대해 두 가지 질문을 할 수 있습니다. 하나는 있습니까? 그 가치는 무엇입니까? -하지만 그것은 호출 코드에서 발생합니다.

값이 필요하지 않으면 다시 가져 오지 않으려 고한다면, 주입 하는게 어떻습니까? 내가 코드를 읽고 있었다 그리고 난 세 번째 버전보다 다른 것을 본다면

interface OptionHandler<T> { 
    public void specified(T optionValue); 
    public void notSpecified(); 
} 

handleOptionIfSpecified("demo", new OptionHandler<Integer>() { 
    public void specified(Integer timeout) { 
     doDemoVersion(timeout); 
    } 
    public void notSpecified() { 
     doRealVersion(); 
    } 
}); 

하지만 심각, 내가 overcomplication을보고 리팩토링을 시작 했죠.투기 적으로 가치를 얻고 null과 null이 아닌 경우를 다르게 처리하는 관용구는 매우 광범위합니다 (Java에서는 최소한). 아무런 의미없는 종류의 순결을 추구하면서 그것을 회피함으로써 유용한 목적은 제공되지 않는다.

+0

첫 번째 버전이 가까워지고 내 보행자를 만족시키는 데 가장 좋은 방법 일 수 있습니다. 두 번째 및 세 번째 버전 Greg에 대한 주석에서 언급 한 것과 동일한 것을 찾습니다. 데모 옵션이 설정된 경우에만 제한 시간 세부 정보가 필요하므로 이상적으로 코드가 데모 블록 내에 캡슐화되기를 바랍니다. 시각적 인 잡음없이 빠르게 스캔 할 수 있습니다. – jontyc

+0

나는 당신을 즐겁게 할지도 모르는 또 다른, 훨씬 더 복잡한 옵션을 추가 할 것이다. –

+0

네, 저를 즐겁게했습니다! :) 그것은 내가 추구하는 순결이 아니며, 어떤 코드라도 읽고 읽을 수있는 것이 가장 빠릅니다. 물론 이것은 여기에 간단한 예제이며 아무거나 (bar injection!)는 누구든지 빨리 읽을 수 있습니다. 나는 마비 분석을 해산시키고 그것에 잠자 게 할 것입니다. – jontyc

1

아마 뭔가 :

bool GetDemoOption(int &timeout); 

int timeout; 
if (GetDemoOption(timeout)) { 
    DoDemoVersion(timeout); 
} else { 
    DoRealVersion(); 
} 

이 쉽게 참조로 다시 옵션 값을 통과 할 수있는 C++에 의존한다. 이것은 Java 나 Python과 같은 값에 의한 엄격한 의미를 가진 언어에서 좀 더 어색합니다. 파이썬에서, 그러나, 하나는 함수에서 하나 개 이상의 값을 반환 할 수 있습니다

exist, timeout = GetDemoOption() 
if exist: 
    DoDemoVersion(timeout) 
else: 
    DoRealVersion() 
+0

여러분의 C++ 예제에서 타임 아웃은 데모 버전과 만 관련이 있으므로 데모를 다루는 블록에 숨기거나 캡슐화하고 싶습니다. 파이썬 예제와 동일합니다. 또한 필자는 PHP와 같은 언어에서 여러 반환 값에 관심을 갖지 않을 것입니다. 특히 PHP를 문서화하기위한 사전 선언이없는 곳에서는 그렇습니다. – jontyc