我正在使用两个第三方库来执行类似的功能。我需要能够决定在运行时使用哪个库(每个库在不同类型的任务中都表现出色,我只知道在运行时特定任务需要哪个库)。
我正在尝试创建一个类,这样我就可以在运行时动态调用特定库的功能。最初,我考虑过使用适配器模式,但问题是两个库都返回不同类型的对象,适配器模式只有在接口(interface)(或签名)相同时才有用。
举个具体的例子,Selenium
框架允许我通过调用 driver.findElement(By.Xpath("XPath"))
在 WebDriver
实例上。同样,XSoup
框架(JSoup
的扩展)允许我通过调用 Xsoup 来执行相同的功能。编译(“XPath”).evaluate(文档).getElements();
。这两种方法的功能在语义上是等价的——但是它们都返回(并期望)两种不同类型的对象(WebDriver
返回一个 WebElement
和 XSoup
返回 Element
的实例 - 两个不同的对象。类似地,WebDriver
需要一个 driver
对象,而 XSoup
需要一个 document
对象作为参数传入)。
我的目标是通过调用单个方法(例如本例中的 getElement()
)来合并两个框架的功能,并让该方法处理调用正确库的细节/框架(例如基于传递给方法的一些参数)
什么设计模式可用于在运行时合并两个库的功能?
谢谢
最佳答案
您在适配器模式方面走在了正确的轨道上。听起来您需要两层。
您首先需要定义一个能够包装 WebElement 和 Element 的通用接口(interface):
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();
}
}
然后您需要定义一个返回这些值的接口(interface),并为 XSoup 和您正在使用的任何其他库提供一个实现。这些实现将只包装库中的返回值:
public interface Driver {
public MyElement findByXpath(String xpath);
}
public class MySeleniumDriver 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();
关于java - 合并两个以上外部库功能的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42882046/