合并两个+外部图书馆功能的设计模式

时间:2017-03-19 01:50:00

标签: java oop design-patterns

我正在使用两个第三方库来执行类似的功能。我需要能够决定在运行时使用哪个库(每个库在不同类型的任务中都是优越的,我只知道在运行时特定任务需要哪个库)。

我正在尝试创建单个类,因此我可以在运行时动态调用特定库的功能。最初,我想过使用适配器模式,但问题是两个库都返回不同类型的对象,并且适配器模式仅在接口(或签名)相同时才有用。

为了提供一个具体示例,Selenium框架允许我通过调用driver.findElement(By.Xpath("XPath"))实例上的方法WebDriver从页面中提取Web元素。同样,XSoup框架(JSoup的扩展名)允许我通过调用Xsoup. compile( "XPath" ).evaluate(doc ).getElements();来执行相同的功能。两种方法的功能在语义上是等效的 - 但它们都返回(并期望)两种不同类型的对象(WebDriver返回WebElementXSoup返回Element的实例 - 两个不同的对象。同样,WebDriver期望driver对象,XSoup期望document对象作为参数传入。

我的目标是通过调用单个方法(例如在这种情况下为getElement())来合并两个框架的功能,并让方法处理调用正确的库/框架的细节(基于某些传递给方法的参数)例如

可以使用哪种设计模式在运行时合并两个库的功能?

由于

1 个答案:

答案 0 :(得分:1)

您使用适配器模式走在正确的轨道上。听起来你需要两个级别。

首先需要定义一个能够包装WebElement和Element的通用接口:

public interface MyElement {
    String getText();
}  

public class SeleniumElement implements MyElement {
    private WebElement element;

    public SeleniumElement(WebElement element) {
        this.element = element;
    }

    public String getText() {
        return element.getText();
    }
}

public class XSoupElement implements MyElement {
    private Element element;

    public XSoupElement(Element element) {
        this.element = element;
    }

    public String getText() {
        return element.text();
    }
}

然后,您需要定义一个返回这些值的接口,并为XSoup和您正在使用的其他库提供一个实现。实现将只包装库中的返回值:

public interface Driver {
    public MyElement findByXpath(String xpath);
}

public class MySelenium Driver implements Driver {
    public MyElement findByXpath(String xpath) {
        return new SeleniumElement(driver.findElement(By.Xpath(xpath)));
    }
}

public class MyXSoupDriver implements Driver {
    public MyElement findByXpath(String xpath) {
        return new XSoupElement(Xsoup.compile(xpath).evaluate(doc).getElement());
    }
}

然后在运行时,您可以更改您使用的框架:

Driver myDriver = isSeliniumBetter ? new MySeliniumDriver() : MyXSoupDriver();

String text = myDriver.findByXPath("xpath").getText();