2017-03-29 3 views
3

SO (예 : Replacing if else statement with pattern)의 다양한 스레드를 기반으로 여러 if/else 문을 Command 패턴으로 바꿀 수 있다는 것을 알고 있습니다.If Else를 디자인 패턴으로 바꾸기

내 상황이 약간 다릅니다.

일련 번호가 Commands이고 이전 명령이 성공적으로 수행되지 않은 경우에만 Command을 실행해야합니다.

예를 들어 가상의 웹 페이지에서 텍스트를 검색해야한다고 가정합니다. 화면 스크래핑을 사용하여 페이지에서 텍스트를 직접 스크랩하거나 API에서 텍스트를 가져올 수 있습니다. 화면 긁기가 성공적이지 않은 경우에만 API에서 텍스트를 가져 오려고합니다. 즉 "긁히는"명령이 작동하지 않으면 "가져 오기"명령 만 실행합니다.

이 경우 스크래핑 된 문자열이 비어 있거나 null과 같은지 테스트 한 다음 두 번째 명령을 실행합니다. 두 번째 명령도 성공하지 못하면 세 번째 명령을 실행하는 등의 작업을 수행합니다.

특정 조건이 참/거짓 인 경우에만 후속 명령을 실행한다는 점이 중요합니다. 조건은 각 명령에 대해 항상 동일하지만 나중에 명령 수가 늘어날 수 있습니다.

I의 (a MapCommand 인터페이스를 사용하여) 일반적으로 제안 된 경로를 통해이를 구현할 수 없습니다 벡 첫 번째가 실패 할 경우이의 (a Command이 성공적인지 아닌지 또한 확인 할 수없는 것) 다음 Command을 실행하지 않을

이 문제를 해결하기 위해 어떤 디자인 패턴을 사용할 수 있습니까?

+1

을 (당신이 chain of responsibility 패턴이 더 적합하다고 생각하고 왜 그렇게 생각하지만 만약 코멘트를 배치하십시오) 내 문제에 대한 단순하고 간단 솔루션입니다 생각 : 실행 이 명령은 성공을 위해'true'를 리턴합니다. 모든 명령을 목록에 넣고 첫 번째 명령이 성공할 때까지 해당 명령의 모든 명령을 실행하십시오. 불행히도 Java Stream에는'takeWhile()'이 없습니다. – dhke

+4

당신은 [책임 패턴의 체인] (https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern)을 찾고 있다고 생각합니다. –

답변

0

다른 사람들이 말했듯이, Chain of Responsibility 패턴을 사용하면 성공할 때까지 다른 구현을 계속 시도 할 수 있습니다.

은의 당신의 명령이 성공하거나 실패 할 경우 null

public interface Command{ 

    Result handle(Request request); 
} 

그런 다음 체인 (또한 부울 또는 Optional 또는 당신이 원하는대로 사용할 수) 경우 처리 요청이 Result 개체를 반환이 인터페이스를 가지고 있다고 가정 해 봅시다 명령은 다른 여러 명령을 감쌀 수 있으며 뭔가 작동 할 때까지 각각의 명령을 시도 할 수 있습니다.

public class ChainedCommand implements Command { 
    //could also be set in a constructor instead 
    List<Command> commandChain = Arrays.asList(new ScrapperCommand(), 
              new ApiCommand()); 


    public Result handle(Request request){ 

     Result result = null; 
     Iterator<Command> iter = commandChain.iterator(); 
     while(result ==null && iter.hasNext()){ 
       result = iter.next().handle(request); 
     } 

     return result; 
    } 
} 
0

사람들은 내가 내가이 문제를 해결하기 위해 Command 패턴의 변화를 사용할 수 나에게 발생한 문제를 생각으로 그러나 chain of responsibility 패턴을 사용하여 제안했다. 이런 식으로 작동합니다.

if 문을 Command 인터페이스를 구현하는 해당 클래스로 바꿉니다. 이 예에서는 클래스 ScreenScrapeTextCommandFetchTextFromAPICommand을 구현합니다. 각 클래스는 Command 인터페이스를 구현할 것이므로 execute() 메서드를 각 클래스에 추가합니다.이 메서드는 화면 스크래핑이나 API에서 가져 오는 것과 같은 기능을 실제로 실행합니다.

그런 다음 모든 관련 명령을 포함하는 새 클래스를 만듭니다. 이 클래스를 GetTextCommandCenter이라고합시다.

commandList.add(new ScreenScrapeTextCommand(); 
commandList.add(new FetchTextFromAPICommand(); 

우리는 다음과 if\else 체인을 대체 할 수 : 클래스 우리는 다음과 같은 방식으로 목록에 처음 두 클래스를 추가하여 다음 하드 코드 명령을 거라고 public List<Command> commandList;의 형태로 Commandslist 포함됩니다 다음과 같습니다 :

명령이 성공적으로 실행되면 while 루프의 조건이 실패하고 그에 따라 메서드가 반환됩니다.

이렇게하면 CommandCenter 클래스에 클래스를 추가하거나 개별 명령의 우선 순위를 빠르게 변경하여 더 많은 명령을 쉽게 추가 할 수 있습니다.

나는이 조건이 명령에 고유 한 경우