我在Kotlin中编写了以下代码:
class ProxyiOSUIElementWrapper(val app: SIMIAppUIElementProtocol) : IAppUIElement {
override fun tap() {
app.tap()
}
override fun elementWithTestId(testId: String): IAppUIElement {
return ProxyiOSUIElementWrapper(app.elementWithTestIdTestId(testId))
}
override fun table(withId: String): IAppUIElement {
return ProxyiOSUIElementWrapper(app.tableWithId(withId))
}
override fun cell(withId: String): IAppUIElement {
return ProxyiOSUIElementWrapper(app.cellWithId(withId))
}
override fun waitForExistence(timeout: Double) {
app.waitForExistenceTimeout(timeout)
}
override fun hasText(text: String, timeout: Double) {
app.hasTextText(text, timeout)
}
override fun getText(timeout: Double): String {
return app.getTextTimeout(timeout)
}
override val debugDescription: String
get() = app.debugDescription
}
class ProxyiOSAppWrapper : IAppWrapper {
private val app = ConcreteAppWrapper(AppSetup.identifier)
override var identifier: String = app.identifier
override fun launch(arguments: Map<String, String>) {
app.launchArguments(arguments as Map<Any?, *>)
}
override fun tap() {
app.tap()
}
override fun elementWithTestId(testId: String): IAppUIElement {
return ProxyiOSUIElementWrapper(app.elementWithTestIdTestId(testId))
}
override fun table(withId: String): IAppUIElement {
return ProxyiOSUIElementWrapper(app.tableWithId(withId))
}
override fun cell(withId: String): IAppUIElement {
return ProxyiOSUIElementWrapper(app.cellWithId(withId))
}
override fun waitForExistence(timeout: Double) {
app.waitForExistenceTimeout(timeout)
}
override fun hasText(text: String, timeout: Double) {
app.hasTextText(text, timeout)
}
override fun getText(timeout: Double): String {
return app.getTextTimeout(timeout)
}
override val debugDescription: String
get() = app.debugDescription
}
actual object AppSingleton {
actual var app: IAppWrapper = ProxyiOSAppWrapper()
}
正如您所看到的,有一些函数正在重复,例如table
、cell
等。如何使其变为DRY?我想从类中取出这些函数,然后只写一次,但由于两个类都必须符合接口,所以我无法做到这一点。我尝试创建一个从两个接口继承的类,但构造函数出现了问题,因为一个Proxy类接受参数,而另一个不接受。
Kotlin不支持多重继承,即一个类不能从两个类继承。但是,一个类可以实现多个接口。如果您只想在一个类中耗尽函数,请再次查看体系结构。例如,下面的体系结构是允许的:类E实现接口A、B,并且只继承自类C。
interfaceA(){
}
interfaceB(){
}
class C(){
}
class D(){
}
class E():A,B,C{
}
而下面的体系结构是不允许的:E类实现接口A、B和C、D。
interfaceA(){
}
interfaceB(){
}
class C(){
}
class D(){
}
class E():A,B,C,D{
}
解决方案是创建一个类,该类将从两个接口继承:IAppWrapper和IAppUIElement,并覆盖那里的方法。我正在粘贴下面的代码:
open class ProxyFunctionsHelper : IAppUIElement,
IAppWrapper {
private val app: Any
constructor(app: SIMIAppUIElementProtocol) {
this.app = app
}
constructor(app: ConcreteAppWrapper) {
this.app = app
}
override val identifier: String
get() = run(
forAppWrapper = { it.identifier },
forUIElementWrapper = { error("unable to cast app - identifier error") }
)
override fun launch(arguments: Map<String, String>) =
run(
forAppWrapper = { it.launchArguments(arguments as Map<Any?, *>) },
forUIElementWrapper = { error("unable to cast app - launch error") }
)
override fun tap() =
run(
forAppWrapper = { it.tap() },
forUIElementWrapper = { it.tap() }
)
override fun elementWithTestId(testId: String): IAppUIElement =
run(
forAppWrapper = { ProxyFunctionsHelper(it.elementWithTestIdTestId(testId)) },
forUIElementWrapper = { ProxyFunctionsHelper(it.elementWithTestIdTestId(testId)) }
)
override fun table(withId: String): IAppUIElement =
run(
forAppWrapper = { ProxyFunctionsHelper(it.tableWithId(withId)) },
forUIElementWrapper = { ProxyFunctionsHelper(it.tableWithId(withId)) }
)
override fun cell(withId: String): IAppUIElement =
run(
forAppWrapper = { ProxyFunctionsHelper(it.cellWithId(withId)) },
forUIElementWrapper = { ProxyFunctionsHelper(it.cellWithId(withId)) }
)
override fun waitForExistence(timeout: Double) {
run(
forAppWrapper = { it.waitForExistenceTimeout(timeout) },
forUIElementWrapper = { it.waitForExistenceTimeout(timeout) }
)
}
override fun hasText(text: String, timeout: Double) {
run(
forAppWrapper = { it.getTextTimeout(timeout) },
forUIElementWrapper = { it.getTextTimeout(timeout) }
)
}
override fun getText(timeout: Double): String =
run(
forAppWrapper = { it.getTextTimeout(timeout) },
forUIElementWrapper = { it.getTextTimeout(timeout) }
)
override val debugDescription: String
get() = run(
forAppWrapper = { it.debugDescription },
forUIElementWrapper = { it.debugDescription }
)
private fun <T> run(
forAppWrapper: (ConcreteAppWrapper) -> T,
forUIElementWrapper: (SIMIAppUIElementProtocol) -> T
): T =
when (val application = app) {
is ConcreteAppWrapper -> forAppWrapper(application)
is SIMIAppUIElementProtocol -> forUIElementWrapper(application)
else -> error("unable to cast app - error")
}
}