我有一个处理数学运算符的程序(+,*, - ,/)。我有一个接口运算符,它有一个像这样的计算方法:
public interface Operator
{
double calculate(double firstNumber,double secondNumber);
}
我有四个类(Plus,Minus,Divide,Multiply)实现了Operator接口,如下所示:
public class Plus implements Operator
{
public double calculate(double firstNumber,double secondNumber)
{
return firstNumber + secondNumber;
}
}
public class Minus implements Operator
{
public double calculate(double firstNumber,double secondNumber)
{
return firstNumber - secondNumber;
}
}
等等......
我使用Map来处理运算符:
static Map<String,Operator> operatorMap = new HashMap<String,Operator>();
static
{
operatorMap.put("+", new Plus());
operatorMap.put("-", new Minus());
operatorMap.put("*", new Multiply());
operatorMap.put("/", new Divide());
}
double output = operatorMap.get(op).calculate(firstNumber,secondNumber);
我应该像这样更改程序:
我有一个文件夹(myfolder)。每个人都可以获取界面并实现自己的操作符并将.class文件放在myfolder中。我的程序也应该工作。这意味着依赖于(+,*, - ,/)应该删除从我的程序。 例如,有些人获得操作员界面并实现%并将.class文件放在我的文件夹中,我的程序仍然可以工作(地图实现必须更改) 谁能帮我? 我很欣赏。
答案 0 :(得分:1)
所以你的意思是你将为一个新的操作符创建一个新类,程序应该自动选择它。如果是这种情况,您可以使用Reflection API来迭代实现Operator接口的可用类。然后将它们添加到地图中。
要删除对hashmap的依赖项,可以在Operator界面中添加一个新方法,如下所示:
public interface Operator
{
double calculate(double firstNumber,double secondNumber);
char getSign();
}
像Plus,Minus这样的所有类都会返回一个映射到其符号的字符。
public class Plus implements Operator
{
public double calculate(double firstNumber,double secondNumber)
{
return firstNumber + secondNumber;
}
public char getSign()
{
return '+';
}
}
接下来,在您的calculate(char operator, int operand1, int operand2)
方法中,您可以首先遍历实现Operator接口的所有类(使用反射),然后调用get sign并将其与传递给此方法的operator参数进行比较,如果符号与运算符,将操作数传递给Operator.calculate()方法。要获取实现Operator接口的所有类,可以使用以下代码:
Reflections reflections = new Reflections("mypackage");
Set<Class<? extends Operator>> classes = reflections.getSubTypesOf(Operator.class);
希望你现在明白了。
答案 1 :(得分:0)
你可以使用工厂模式来实现这个如果你正在使用java 8那么String可以用作switch case的一部分否则你需要尝试char或int: -
public class MyFactory {
private MyFactory() {
}
public static Operator getOperator(String operator) {
switch (operator) {
case "+":
return new Plus();
case "-":
return new Minus();
case "*":
return new Multiply();
case "/":
return new Divide();
case "%":
return new Modulo();
}
}
}
然后致电: -
Operator op = MyFactory.getOperator("+");
op.calculate(firstNumber,secondNumber);
答案 2 :(得分:0)
您可以使用URLClassLoader
从给定文件夹动态加载类。请注意,您还需要以某种方式指定运算符名称。假设接口中有一个特殊的方法,如下所示:
public interface Operator
{
String getOperator();
double calculate(double firstNumber,double secondNumber);
}
你实现它是这样的:
public class Plus implements Operator
{
@Override
public double calculate(double firstNumber,double secondNumber)
{
return firstNumber + secondNumber;
}
@Override
public String getOperator() {
return "+";
}
}
然后你可以加载给定文件夹中的所有操作符,如下所示:
Map<String, Operator> initOperators(File folder) {
File[] files = folder.listFiles();
Map<String, Operator> operators = new HashMap<String, Operator>();
if(files == null)
return operators;
URLClassLoader cl;
try {
cl = new URLClassLoader(new URL[] {folder.toURI().toURL()});
} catch (MalformedURLException e) {
return operators;
}
for(File file : files) {
String name = file.getName();
if(name.endsWith(".class")) {
try {
String className = name.substring(0, name.length()-".class".length());
Operator op = cl.loadClass(className)
.asSubclass(Operator.class)
.newInstance();
operators.put(op.getOperator(), op);
} catch (ClassNotFoundException e) {
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
} catch (ClassCastException e) {
} catch (NoClassDefFoundError e) {
}
}
}
return operators;
}
在我的示例中,例外被忽略,您可能决定以更合适的方式处理它们。