>

오늘 일찍 다리 디자인 패턴의 예를 구현하려고했습니다. , 그러나 나는 그것을 잘못 해석하게되었습니다.

많이 변경했습니다 :

public interface VisitorAPI {
    String visit (String url);
}

<시간>

public class JsoupVisitorAPI implements VisitorAPI {
    @Override
    public String visit(String url) {
        try {
            return Jsoup.connect(url).timeout(TIMEOUT).userAgent(USER_AGENT).postDataCharset(CHARSET).get().html();
        } catch (IOException e) {
            return "";
        }
    }
}

<시간>

public class JauntVisitorAPI implements VisitorAPI {
    private UserAgent userAgent;
    public JauntVisitorAPI(UserAgent userAgent) {
        this.userAgent = userAgent;
    }

    @Override
    public String visit(String url) {
        try {
            return userAgent.visit(url).innerHTML();
        } catch (ResponseException e) {
            return "";
        }
    }
}

<시간>

public class HtmlUnitVisitorAPI implements VisitorAPI {
    WebClient webClient;
    public HtmlUnitVisitorAPI() {
        this.webClient = createWebClient();
    }
    @Override
    public String visit(String url) {
        Page p = null;
        try {
            p = webClient.getPage(url);
            return p.getWebResponse().getContentAsString(Constants.CHARSET);
        } catch (IOException e) {
            return "";
        }
    }
    private WebClient createWebClient() {
        WebClient webClient = new WebClient(BrowserVersion.FIREFOX_38);
        webClient.getOptions().setJavaScriptEnabled(true);
        webClient.getOptions().setCssEnabled(false);
        webClient.getOptions().setThrowExceptionOnScriptError(false);
        webClient.setAjaxController(new NicelyResynchronizingAjaxController());
        webClient.waitForBackgroundJavaScript(Constants.TIMEOUT);
        return webClient;
    }
}

<시간>

public interface ParserAPI<T> {
    T parseDocument (String htmlCode);
}

<시간>

public class JSoupParseAPI implements ParserAPI<Document> {
    @Override
    public Document parseDocument(String htmlCode) {
        Document doc = Jsoup.parse(htmlCode);
        doc.charset(Charset.forName(CHARSET));
        return doc;
    }
}

<시간>

public class JauntParserAPI implements ParserAPI<Document> {
    private UserAgent userAgent;
    public JauntParserAPI(UserAgent userAgent) {
        this.userAgent = userAgent;
    }
    @Override
    public Document parseDocument(String htmlCode) {
        try {
            return userAgent.openContent(htmlCode);
        } catch (ResponseException e) {
            //I don't want to return Null, but its difficult to implement an Empty Jaunt Document
            return null;
        }
    }
}

<시간>

public interface CrawlerAPI {    
    String visit(String url);    
    <T> T parse(String htmlCode);    
}

<시간>

public class CrawlerAPIImpl implements CrawlerAPI {
    private VisitorAPI visitorAPI;
    private ParserAPI parserAPI;
    public CrawlerAPIImpl(VisitorAPI visitorAPI, ParserAPI parserAPI) {
        this.visitorAPI = visitorAPI;
        this.parserAPI = parserAPI;
    }
    @Override
    public String visit(String url) {
        return visitorAPI.visit(url);
    }
    @Override
    public <T> T parse(String htmlCode) {
        return (T) parserAPI.parseDocument(htmlCode);
    }
}

public interface Constants {
    String CHARSET = "ISO8859_1";
    int TIMEOUT = 20000;
    String USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36";
}

그래서 이렇게 사용합니다 :

public class CrawlerAPIImplTest {
    CrawlerAPI crawlerAPI;
    @Before
    public void setUp() {
        crawlerAPI = new CrawlerAPIImpl(new HtmlUnitVisitorAPI(), new JSoupParseAPI());
    }
    @Test
    public void testVisit() throws Exception {
        String visit = crawlerAPI.visit("http://www.angeloni.com.br/super/index?grupo=20");
        assertNotNull(visit);
        assertNotEquals("", visit);
    }
    @Test
    public void testParse() throws Exception {
        Document document = crawlerAPI.<Document>parse("<html> <body> </body> </html>");
        assertNotNull(document);
    }
}

브리지 패턴 의 올바른 구현입니까?

  • 답변 # 1

    예, 구현 한 것은 브리지 패턴과 매우 비슷합니다. 브리지 패턴을 절대로 적용하지 않았다는 것을 인정해야합니다. 차라리 비슷한 전략 패턴의 관점에서 생각합니다.

    브리지 패턴 100 %의 목적을 전혀 이해하지 못했기 때문에 나는 그것에 대해 조금 읽었습니다. 주요 차이점은 전략 패턴은 런타임에 다른 전략을 전환하는 데 사용되는 반면 브리지 패턴은 일부 기능의 특정 구현 (예 : 공급 업체별 코드)에 대한 종속성을 피함으로써 클래스를 미래에 대비하는 것입니다 변경해야합니다.)

    후자는 기본적으로 당신이하는 일입니다. 당신의 Crawler   Visitor 에 의존  그리고 Parser  (나는 당신이 ...API 를 떨어 뜨릴 것을 제안합니다  구체적인 구현이 아닌 인터페이스에만 적용됩니다. 그런 다음 Crawler 를 변경하지 않고도 다른 클래스 또는 클래스 계층을 가질 수 있습니다.  코드.

    이렇게하면 Crawler 를 서브 클래 싱 할 수 있습니다  다른 차원에서 변형을 만들 수 있습니다 (다른 클래스로 쉽게 추출 할 수없는 크롤링 전략 일 수 있음). 구현은 하나만 있지만 인터페이스를 제공하여 구현이 다를 수 있음을 나타 냈습니다 (이 경우 항상 가지고있는 두 필드를 재사용 할 수 있으므로 추상 클래스를 갖는 것이 더 적합 할 수 있습니다).

    브릿지 패턴의 좋은 예라고 생각합니다.

  • 이전 c# - 블로흐의 빌더 패턴/업데이터
  • 다음 performance - TI-84의 이중 적분 솔버