我正在使用两个第三方库来执行类似的功能。我需要能够决定在运行时使用哪个库(每个库在不同类型的任务中都是优越的,我只知道在运行时特定任务需要哪个库)。
我正在尝试创建单个类,因此我可以在运行时动态调用特定库的功能。最初,我想过使用适配器模式,但问题是两个库都返回不同类型的对象,并且适配器模式仅在接口(或签名)相同时才有用。
为了提供一个具体示例,Selenium
框架允许我通过调用driver.findElement(By.Xpath("XPath"))
实例上的方法WebDriver
从页面中提取Web元素。同样,XSoup
框架(JSoup
的扩展名)允许我通过调用Xsoup. compile( "XPath" ).evaluate(doc ).getElements();
来执行相同的功能。两种方法的功能在语义上是等效的 - 但它们都返回(并期望)两种不同类型的对象(WebDriver
返回WebElement
而XSoup
返回Element
的实例 - 两个不同的对象。同样,WebDriver
期望driver
对象,XSoup
期望document
对象作为参数传入。
我的目标是通过调用单个方法(例如在这种情况下为getElement()
)来合并两个框架的功能,并让方法处理调用正确的库/框架的细节(基于某些传递给方法的参数)例如
可以使用哪种设计模式在运行时合并两个库的功能?
由于
答案 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();