【问题标题】:Extend Multiple Classes in Java while Retaining Functionality of each Class在 Java 中扩展多个类,同时保留每个类的功能
【发布时间】:2017-08-06 18:47:51
【问题描述】:

我正在使用WebDriver (Selenium),我想向WebDriver 添加自定义方法,例如driver.performCustomAction()

因为我可以实例化FirefoxDriverChromeDriver 的实例,所以我不能简单地扩展FirefoxDriver,因为我将无法使用Chrome 驱动程序的功能。

Tech 我可以创建一个新类并将 WebDriver 的实例传递给构造函数(因此它可以是 FF 或 Chrome)但是我将无法执行每个类的所有非自定义操作,例如findElements(), getText() 在新对象上。

换句话说,如果我的新类被称为 WrappedWebDriver 并且我实例化它的一个新实例,如下所示:

WebDriver FFDriver = new FirefoxDriver();
WrappedWebDriver WDriver = new WrappedWebDriver(FFDriver);

我将能够调用WDriver.performCustomAction(),但我将无法调用WDriver.findElement()FirefoxDriver 类中定义的任何其他方法(或我可以使用FFDriver 执行的操作)。

如何添加适用于FirefoxDriverChromeDriver 的新方法,而无需编写两次,同时保留每个相应类的所有功能?

P.S:我知道 Java 不允许多重继承,还有其他方法吗?

【问题讨论】:

  • 接口怎么样?
  • 或者是一个同时包装了 FirefoxDriver 和 ChromeDriver 的包装类
  • 你写一个新的类WrappedWebDriver 实现WebDriver 接口,并在构造函数中使用WebDriver 怎么样?您必须实现接口中定义的方法,但您只需调用您传入的方法的驱动程序。
  • 有些人在他们的包装器中使用装饰器模式,基本上像public WebElement findElement(By by){return this.driver.findElement(by)}这样复制你想要的方法如果你实现WebDriver接口它会迫使你装饰整个东西,但是让您针对该接口编写的代码仍然可以工作。如果这让您感到难过,您还可以通过 wrappedWebDriver.getDriver().FindElement... 公开访问 driver
  • 或者您可以使用 C# 并仅使用扩展方法 :) IMO 实现 WebDriver 接口并将所有调用转发给驱动程序是正确的方法,即使它感觉像代码过分了

标签: java selenium inheritance multiple-inheritance


【解决方案1】:

我认为您可以创建包含 Webdriver 实例的 Wrapper 类,并且您将包装您想要支持的 webdriver 的方法。例如,您可以这样做:

 public class WrappedWebDriver {

    public WebDriver driver;

    public WrappedWebDriver(WebDriver driver){
        this.driver = driver
    }

    public WebElement find(By by){
        //your customization code
        return driver.findElement(by);
    }

    public void setText(By by, String text){
        //your customization code
        driver.findElement(by).sendKeys(text)
    }

    public void performCustomAction(){
       //your customization code 
    }

}

您可以通过在包装方法中添加一些功能来自定义 Webdriver 标准方法。通过公开驱动程序,您可以让用户在使用标准驱动程序方法或自定义方法之间进行选择。

对于名为 Conductor 的 selenium,有一个很好用的 Wrapper API。 https://github.com/conductor-framework/conductor。在那里您可以找到更复杂的如何包装 WebDriver 的示例。

【讨论】:

    【解决方案2】:

    您可能需要扩展EventFiringWebDriver。这个类的行为本质上是复合的(它是通过引用现有的 webdriver 实例创建的),它最初设计用于利用所有 webdriver 发起操作的前/后事件。但它非常适合您的目的。

    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.support.events.EventFiringWebDriver;
    
    public class WrappedDriver extends EventFiringWebDriver {
        public WrappedDriver(WebDriver driver) {
            super(driver);
        }
    
        public void performCustomAction(){
            //your customization code 
        }
    }
    

    所以本质上,您首先构建一个装饰器,该装饰器实现了实际RemoteWebDriver 子类将实现的所有接口,然后让您的自定义类扩展装饰器。本例中的装饰器类为EventFiringWebDriver

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-19
      • 2016-01-15
      • 1970-01-01
      • 1970-01-01
      • 2016-03-29
      相关资源
      最近更新 更多