2016-10-20 4 views
0

우리의 응용 프로그램은 많은 원시 필드 및 부울 문맥이 거의 모든 흐름의 주위에 전달하고, 결정이 부울 플래그에 따라 촬영으로 상황 클래스 주위에 어느 정도 내장되어 있습니다. 이제 새로운 기능을 구현하기 위해 새로운 부울이 컨텍스트에 추가되었으며 10 개의 다른 장소에서 확인해야합니다. 일반적인 흐름은이 예제와 비슷한 구조를가집니다.리팩터링 부울 기반 흐름

public void handle(context) { 
    if (context.isBig()) 
    drawBigThing(context) 
    else 
    drawSmallThing(context) 
    //more code 
    ...... handleColor(context) //somewhere deeper in the flow/stack 

} 

private void handleColor(context) { 
    if (context.isBig()) 
    takeMoreColor(context.getColor()) 
    else 
    takeLessColor(context.getColor()) 
} 

코드의 다른 부분에서 볼 수 있듯이 우리는 같은 플래그를 되돌아 보지만 그에 따라 다른 결정을 내립니다. 이제 context.isVeryBig()을 추가하면 어떻게 폭발 할 수 있는지보실 수 있습니다.

다른 책임을 지닌 메소드/클래스에서 쿼리되었지만 여전히 동일한 플래그에 관심이있는 부울 플래그를 리팩터링하는 몇 가지 아이디어가 있습니까?

하나의 아이디어는 부울 플래그를 보관하지 않고 각 책임에 대한 주/전략을 유지하는 것이지만 상황에 따라 책임이 누출됩니다 (어쨌든 분리 될 수 있습니까?). IFs이지만 최소한 하나의 위치에 그룹화되어 흐름이 시작되기 전에

+1

A)의 두 번째 답변 예 , 그런 접근법을 제거하는 것이 좋습니다. 당신은 기본적으로 거기에 많은 글로벌 상태를 가지고 있으며, 필드에 직접 액세스하여 더 좋게 만들지 않습니다. B) 상태 및 Statemachine 및 다형성은 OO에서 "일반적인"답변입니다. – GhostCat

+0

사례 IMO에 적용되는 https://sourcemaking.com/refactoring/smells/switch-statements를 참조하십시오. – JnRouvignac

답변

0

이것은 개념적인 질문입니다. 그래서, 아마도 나는 그것에 완전히 대답하지 않습니다.

하나 개의 아이디어가 문맥 똑똑하게하는 것, 부울 플래그 하지만 책임의 각 국가/전략을 보유하지, 그러나 이것은 아마 어떻게 든 그들은 이 분리 될 수 있습니다 (맥락에서 책임을 누설?)

전략을 사용하는 것이 좋습니다. 그럼에도 불구하고 컨텍스트를 너무 똑똑하게 만들지는 않을 것입니다. 컨텍스트에 데이터가 포함되어 있거나 이름이 잘못되어 책임이 있습니다.

컨텍스트와 처리를 분리 할 수 ​​있는지 궁금합니다. 당신은 할 수 있고 그렇게해야한다고 생각합니다.

난 여전히 IF를있을 것이다 그러나 적어도 그들은 하나 개 장소로 그룹화되고 흐름은 동의

을 시작하기 전에. 왜 계약에 의해 통신하고 반환 된 구현에서보다 융통성을 갖기 위해 팩토리 클래스에 없습니까?

주제를 다루는 두 가지 방법을 제안합니다.

1) 콘크리트 핸들러에 의한 처리의 전체 구현 유연한 처리

인터페이스 : (필요의 동작을 확인하여 booleaans 따른

public interface FlowHandler{ 

    void handle(Context context); 
} 

및 구현 예로서

변경 될 흐름) :

public class BigFlowHandler implements FlowHandler { 

    public void handle(Context context){ 
      drawBigThing(context); 
      takeMoreColor(context.getColor()) 
    } 
} 

각 설계가 유연하기 때문에 설계가 유연합니다. 원하는대로 문제를 처리 할 수 ​​있습니다.

그럼에도 불구하고 작업이 모든 핸들러에 대해 동일한 순서로 실행되고 동일한 방향으로 실행되어야하는 경우이 방향으로 밀어 넣는 다른 디자인을 사용할 수 있습니다. 제약 단계를 처리하고 단계의 처리를 인수 분해하는

2) 미리 정의 된 프로세스를

당신은 어떤을 위해 작업을 필요로하는 체인) (구체적인 클래스 FlowHandler을 구체적인 방법 (handle(Context context)를 선언함으로써 그것을 할 수

실행 된 흐름. 호출 된 연산은 전략으로 구현 된 팩토리 메소드에 의존합니다. 하여 무엇 질문에
구체적인 클래스 (FlowHandler) 답합니다 (프로세스의 단계와 순서)의 방법 (프로세스의 단계의 구현)

public interface HandlerOperations{ 
drawThing(Context context); 
takeColor(Context context); 
} 

public class FlowHandler{ 

    public FlowHandler(HandlerOperations handlerOperations){ 
      this.handlerOperations = handlerOperations; 
    } 

    public void handle(Context context){ 
      handlerOperations.drawThing(context); 
      handlerOperations.takeColor(context); 
    } 
}