首先,让我们定义接口:
public interface Transformable<T> {
<R extends Transformable<T>> R registerTransformation(Function<T,T> transformation);
T process(T entity);
}
public interface HttpService<T> {
T execute(URL url);
}
如界面所示 Transformable<T>
,我们可以创建一个简单的生成器模式来注册转换并在一行中执行所有转换,例如:
new DefaultTransformableImpl<Integer>(){}
.registerTransformation(number -> number * 2)
.registerTransformation(number -> number - 1)
.registerTransformation(number -> number * number)
.process(109845)
好了,现在我们准备创建 HttpService
. 这样做的目的是提供修改标头、http方法。。。在实际将请求发送到服务器之前,不需要为连接示例指定方法适配器 org.jsoup.Connection
接口:
import java.util.function.Function;
import java.util.List;
import java.net.URL;
import org.jsoup.Connection;
import org.jsoup.helper.HttpConnection;
import org.jsoup.nodes.Document;
import lombok.SneakyThrows;
public class JsoupHttpService implements HttpService<Document>, Transformable<Connection> {
private final List<Function<Connection, Connection>> fns = new LinkedList<>();
@Override public <R extends Transformable<Connection>> R registerTransformation(Function<Connection, Connection> transformation) {
this.fns.add(transformation);
return (R) this;
}
@Override public Connection process(Connection connection) {
return fns.stream().reduce(Function.identity(), Function::andThen).apply(connection);
}
@SneakyThrows
@Override public Document execute(URL url) {
return this.process(HttpConnection.connect(url)).execute().parse();
}
}
这只是实际实现的简化,只关注问题的必要部分,这可以通过尝试使用 JsoupHttpService
使用方法链接:
public Document doSomething() {
return new JsoupHttpService(){}
.registerTransformation(connection -> connection.method(Connection.Method.GET))
.registerTransformation(connection -> connection.userAgent("fake user-agent"))
.execute("https://www.google.com")
.parse();
}
如果您在ide中尝试这个方法,它会说一些接近于无法解析“transformable”中的方法“execute”。。。所以我想知道你们是否知道我如何在不修改两个接口的情况下解决这个问题。是我创建另一个接口的唯一选择 HttpService
并尝试调整中定义的方法 Transformable
在里面?
2条答案
按热度按时间ss2ws0br1#
我建议几乎所有使用多重继承的方法,甚至是接口,都是一个坏主意。而且,将泛型和类型继承混合在一起会导致噩梦般的混乱——看看这些奇怪的结构
Comparable
以及Enum
.显然这并不能阻止我修改代码。
如果方法的类型参数仅用于返回类型,则该方法的选项为:return
null
,抛出异常,执行堆类型污染,不必费心返回或更糟。对于构建器的这类问题,解决方法是使用递归定义的类型参数混乱地参数化构建器类型,并可能添加一个抽象的“get this”方法(如果
Transformable
是抽象的,所以可以有字段。为了“得到这个”假设
Transformable
有一个通用的默认实现方法然后在
JsoupHttpService
:ffvjumwh2#
问题是
registerTransformation
返回一个Transformable
. 一Transformable
不是一个HttpService
.您可以通过以下方式实现您想要的:
似乎可转换接口的作者没有正确理解何时使用它是合适的
extends
. 未经检查的演员(R)
应该是个线索。