Java 不使用比较器,通过不同属性比较对象
通常,当您想要比较使用不同属性的对象时,比较器是最佳选择 (参见示例)。 然而,在我的特殊情况下,我不确定是否使用比较器 问题如下:我定义了一个通用接口,名为Java 不使用比较器,通过不同属性比较对象,java,oop,compare,design-patterns,Java,Oop,Compare,Design Patterns,通常,当您想要比较使用不同属性的对象时,比较器是最佳选择 (参见示例)。 然而,在我的特殊情况下,我不确定是否使用比较器 问题如下:我定义了一个通用接口,名为节点,它是共享的 由不同的组成部分组成。还有一个扩展节点的CostNode,以及一个ScoreNode 它扩展了成本节点: 公共接口节点{ S get(); //更多方法。。。 } 公共接口CostNode扩展节点{ //这种方法闻起来很难闻 int compareByCost(可比节点); } 公共接口ScoreNode扩展了CostNo
节点
,它是共享的
由不同的组成部分组成。还有一个扩展节点的CostNode
,以及一个ScoreNode
它扩展了成本节点
:
公共接口节点{
S get();
//更多方法。。。
}
公共接口CostNode扩展节点{
//这种方法闻起来很难闻
int compareByCost(可比节点);
}
公共接口ScoreNode扩展了CostNode{
//int compareByCost(CostNode节点)(来自CostNode)
int compareByScore(ScoreNode节点);
}
在这一点上,有人会争论:你不需要CostNode和ScoreNode,你需要
可以使用不同的比较器来比较节点。没关系。但现在“问题”来了:
我有一个名为Client的组件,它使用ScoreNodes。客户端需要一个节点工厂,
由负责创建ScoreNodes的用户提供:
public class Client {
// ...
public Client(NodeFactory<S, ScoreNode<S>> nodeFactory){...}
public void process() {
while(...){
S current = get();
S old = getOld();
// ...
ScoreNode<S> next = this.nodeFactory.create(current,...));
// Comparisons performed
if (next.compareByCost(old) <=0){
//...
}
if (next.compareByScore(old) > 0){
// ...
}
}
}
}
公共类客户端{
// ...
公共客户端(NodeFactory NodeFactory){…}
公共程序(){
而(…){
S current=get();
S old=getOld();
// ...
ScoreNode next=this.nodeFactory.create(当前,…);
//进行的比较
if(next.compareByCost(旧)0){
// ...
}
}
}
}
如您所见,比较节点的行为嵌入到节点中,并且
与所使用的工厂密切相关(不同的节点需要不同的工厂
和不同的比较器)
另一方面,如果我使用比较器,我必须向客户提供三个组件:
CostComparator、ScoreComparator和NodeFactory。在这个场景中,我只能使用节点
忘记CostNode
和ScoreNode
:
公共类ConcreteNodeCostComparator实现Comparator{
公共整数比较(节点a、节点b){
返回Double.compare((ConcreteNode)a.getCost(),((ConcreteNode)b.getCost());
}
}
公共类ConcreteNodeScoreComparator实现Comparator{
公共整数比较(节点a、节点b){
返回Double.compare((ConcreteNode)a.getScore(),((ConcreteNode)b.getScore());
}
}
然而,我并不真的喜欢这个替代方案,因为在这种情况下,我必须再提供两个组件
对于客户端,当比较方法强烈依赖于节点时
我想我在这个设计中遗漏了一些东西。你觉得怎么样?你应该看看你链接的帖子中Boune的答案。 () 您可以在ScoreNode界面(或其他地方)中使用这种枚举,并使用:
您不必向客户提供更多组件。我在另一篇文章中看到了漂亮的enum comparator。虽然代码很优雅,但问题是我必须将要与之比较的值放在枚举中,这会破坏ScoreNode的可重用性。
public class Client {
// ...
public Client(NodeFactory<S, ScoreNode<S>> nodeFactory){...}
public void process() {
while(...){
S current = get();
S old = getOld();
// ...
ScoreNode<S> next = this.nodeFactory.create(current,...));
// Comparisons performed
if (next.compareByCost(old) <=0){
//...
}
if (next.compareByScore(old) > 0){
// ...
}
}
}
}
public class ConcreteNodeCostComparator implements Comparator<Node<S>> {
public int compare(Node<S> a, Node<S> b){
return Double.compare(((ConcreteNode<S>)a).getCost(), ((ConcreteNode<S>)b).getCost());
}
}
public class ConcreteNodeScoreComparator implements Comparator<Node<S>> {
public int compare(Node<S> a, Node<S> b){
return Double.compare(((ConcreteNode<S>)a).getScore(), ((ConcreteNode<S>)b).getScore());
}
}
ScoreNode.Order.ByCost.compare(node1, node2);
ScoreNode.Order.ByScore.compare(node1, node2);