我正在自己的个人图书馆中使用SikuliX's API。我的想法是在外部项目中单独引用我的库,其中包含了我需要的SikuliX部分。
现在,SikuliX抛出一个FindFailed
异常,我需要它。我试着这样做:
public class FindFailed extends org.sikuli.script.FindFailed {
FindFailed(String msg) { super(msg); }
}
这似乎有道理。但是,当尝试在其中一个方法中使用throws
语句时:
import org.mylibrary.exceptions.FindFailed;
public static boolean clickFinishButton() throws FindFailed {
pattern = PatternManager.loadPattern("my-image.png");
screen.wait(pattern, 10);
region = screen.exists(pattern);
region.click(pattern);
return true;
}
我仍然收到Unhandled exception type FindFailed
警告。将其更改回原始org.sikuli.script.FindFailed
当然会有效,但在外部项目中使用try-catch
将需要我重新添加相关的SikuliX jar文件。
我想做的是简单地包装SikuliX抛出的FindFailed
异常,并在我的库内部和外部使用它。
所有这一切的主要目标是使用我自己的其他方法来包装另一个API,这样当我引用这个库时,后面的项目也不必引用SikuliX的jar。
- - - - My Library - - - <—————— External Project
| |
| SikuliX |
- - - - - - - - - - - -
就像现在一样,我要求做以下事情:
- - - - My Library - - - <—————— External Project
| | |
| SikuliX | |
- - - - - - - - - - - - v
SikuliX (Again)
到目前为止,我改变了以下似乎有效的方法。
public class FindFailed extends Exception {
public FindFailed(Throwable cause) { super(cause); }
}
我现在不延长任何第三方例外情况。而我继续做以下事情:
public static boolean clickNewScan() throws FindFailed {
pattern = PatternManager.loadPattern("my-image.png");
region = screen.exists(pattern);
try {
screen.wait(pattern, 60);
region.click(pattern);
} catch (org.sikuli.script.FindFailed e) {
throw new FindFailed(e);
}
return true;
}
答案 0 :(得分:5)
您可以通过将SikuliX中的所有调用包装在自己的接口中来完成此操作。我不知道SikuliX
,所以我会做一个玩具示例。
package third.party.library;
public class Foo {
public void doSomething() throws ThirdPartyException {
// Their code
}
}
好的,所以你想要包装这个功能而不依赖于他们的库。
package juxhin;
public interface FooBehavior {
public void doSomething() throws MyException;
}
然后,当您需要他们的行为时,您可以使用自己的实现:
package juxhin; // YOU write this class
public class ThirdPartyFooBehavior implements FooBehavior {
private final Foo foo;
public FooThirdPartyFooBehavior(Foo theirObject) {
this.foo = theirObject;
}
@Override
public void doSomething() throws MyException {
try {
foo.doSomething();
} catch (ThirdPartyException e) {
throw new MyException(e);
}
}
}
一旦你将你的库包装在你自己的所有接口之后,那么你的类只依赖于你自己的接口,这意味着你不必担心它们的异常。只要您使用非依赖实现重新实现这些接口,它们的库就可以完全删除。
请注意,MyException
不应延长third.party.library.ThirdPartyException
,因为这对您的问题没有帮助;它应该使用Exception(Throwable cause)
构造函数并将其从org.sikuli.script
类层次结构中删除。
但最重要的是,您仍然必须以某种方式包含SikuliX中包含的代码。这就是Maven之类的工具存在的原因,因此添加对jar的引用非常简单。例如,如果您的jar依赖于SikuliX
,那么当您告诉您的新项目使用您的jar时,它会自动包含SikuliX
引用而无需您执行任何操作。你最终会得到像这样的依赖树,它会自动为你完成所有这些工作:
我个人使用Maven但是还有其他选项,例如Ivy和Gradle,它们做同样的事情 - 我不是在这里提倡任何特定的工具,只是提倡使用任何依赖工具。
答案 1 :(得分:1)
从你不拥有的课程扩展永远不是一个好主意,应该避免。此外,它会使处理你的异常的人仍然拥有包含org.sikuli.script.FindFailed的jar。
更好的方法是将这样的异常包装起来:
public class MyFindFailedException extends Exception {
MyFindFailedException(String message, Exception cause) {
super(message, cause);
}
}
然后像这样使用它:
public static boolean clickFinishButton() throws MyFindFailedException {
try {
pattern = PatternManager.loadPattern("my-image.png");
screen.wait(pattern, 10);
region = screen.exists(pattern);
region.click(pattern);
return true;
} catch (FindFailed e) {
throw new MyFindFailedException("something went wrong", e);
}
}