我的建议是使用比较器.请参阅下面的类的草图.
import java.util.HashMap;
import java.util.Map;
public abstract class Calculator {
public static Map weights;
static {
weights = new HashMap();
weights.put("price", 10);
weights.put("gender", 2);
weights.put("geo", 5);
}
public abstract int calculate(Map request);
public abstract int fitnessFor(Map request);
}
您可以使用权重来调整各个请求参数的相对重要性.
import java.util.Map;
public class Calculator1 extends Calculator {
public int calculate(Map request) {
return -1;
}
@Override
public int fitnessFor(Map request) {
int fitness = -1;
Integer price = request.get("price");
if (price == null)
return fitness;
if (price > 10)
fitness += weights.get("price");
return fitness;
}
public String toString() { return "Calculator1"; }
}
Calculator1只在乎昂贵的物品.
import java.util.Map;
public class Calculator2 extends Calculator {
public int calculate(Map request) {
return -1;
}
@Override
public int fitnessFor(Map request) {
int fitness = -1;
Integer price = request.get("price");
if (price == null)
return fitness;
if (price < 5)
fitness += weights.get("price");
Integer gender = request.get("gender");
if (gender == null)
return fitness;
if (gender == 1)
fitness += weights.get("gender");
return fitness;
}
public String toString() { return "Calculator2"; }
}
Calculator2在乎价格较低的物品,尤其是.如果他们是性别1.
比较器仅根据计算器相对于请求的适用性来比较计算器:
import java.util.Comparator;
import java.util.Map;
public class CalcComparator implements Comparator {
private Map request;
public CalcComparator(Map request) {
this.request = request;
}
@Override
public int compare(Calculator c1, Calculator c2) {
int c1Fitness = c1.fitnessFor(request);
int c2Fitness = c2.fitnessFor(request);
if (c1Fitness == c2Fitness)
return 0;
if (c1Fitness < c2Fitness)
return 1;
return -1;
}
}
试试看:
public class Main {
public static void main(String[] args) {
Map request = new HashMap();
request.put("price", 5);
request.put("gender", 1);
List calculators = new ArrayList();
calculators.add(new Calculator1());
calculators.add(new Calculator2());
Collections.sort(calculators, new CalcComparator(request));
System.out.println("For request: "+request);
for (Calculator c : calculators) {
System.out.println(""+c.toString() + "( fitness " + c.fitnessFor(request) + ")");
}
}
}
这只是一个草图来说明这个想法.您可能会想为请求参数引入一个枚举,可能会引入一个Request类,最有可能完全改变适应度的计算方式,将某些字段设为私有并封装它们,等等.
好处是,您可以根据它们对请求的适用性轻松获得所有计算器的订购.