这是在求职面试中使用的编程测试。我发现它有一个非常奇怪的非OO视角,并想知道为什么有人会从这个角度来看待构造函数。作为一名非常有经验的Java程序员,我立即质疑编写此代码的个人的能力以及该问题的奇怪观点。
我发现这些奇怪的脱离背景问题令人不安。我希望得到其他经验丰富的OO Java程序员的反馈。
完成Solver构造函数,以便对solveAll的调用返回包含2个值的列表 包括平方根和作为参数传递的整数的倒数。
public interface MathFunction {
double calculate(double x);
}
public class Solver {
private List<MathFunction> functionList;
public Solver() {
//Complete here
}
public List<Double> solveAll(double x) {
List<Double> result = new ArrayList<Double>();
for (MathFunction function : this.functionList) {
result.add(new Double(function.calculate(x)));
}
return result;
}
}
答案 0 :(得分:38)
这是通过使用最简单的方法测试您的设计模式。我认为这可能是战略(或其他一些行为模式)。见这些:
http://en.wikipedia.org/wiki/Strategy_pattern
http://en.wikipedia.org/wiki/Behavioral_pattern
如果您正在进行Java面试,您应该能够确定他们所暗示的设计模式,这样可以防止您过于不稳定!
要回答这个问题,请根据需要创建两个实现MathFunction
的类,然后创建两个实例并将它们存储在functionList
中。
这里的要点是不'你可以用这种奇怪的方式进行计算',它是'你可以识别设计模式'。
答案 1 :(得分:31)
我同意这是令人困惑和过度设计的。
但我确实认为代码是合理的面向对象的。这是战略模式的一个实例。生成答案列表的代码并不关心如何计算答案 - 这两个问题是分开的,可以应用不同的计算策略而无需触及生成列表的代码。 / p>
为了使类更有用,这些函数应该从外部传递(即依赖注入),而不是在构造函数中实例化。
我知道答案,但我认为这是值得的......
public Solver() {
functionList = new ArrayList<MathFunction>();
functionList.add(new MathFunction() {
@Override
public double calculate(double x) {
return 1d/x;
}
});
functionList.add(new MathFunction() {
@Override
public double calculate(double x) {
return Math.sqrt(x);
}
});
}
答案 2 :(得分:6)
Solver
是通用名称,默认情况下不应实现特定操作。然而,也许这是采访的一部分?第一部分:简单地完成请求。第二部分:说这样做很奇怪。
我想说一个更好的方法是使用addMathFunction(MathFunction mf)
方法。如果需要,可以创建扩展Solver
类的子类,并在其构造函数中添加MathFunction。
答案 3 :(得分:3)
虽然我同意这可能不是最好的方式,或者大多数OO方式来做到这一点,但我必须假设这个练习的目的是看你对继承,接口和匿名内部类的理解程度。这是我唯一能想到的。
答案 4 :(得分:3)
我认为他们希望你在功能列表中添加两个项目。每个都将实现MathFunction接口,一个用于平方根,一个用于反向。 问题在于细节:
1-你有一个返回2个值的函数,因为它有两个不同的东西,那就是坏的
2-如果你想要这个“do-it-all”类,那么接收Mathfunctions作为参数会很有趣,这样你可以做任何类型的MathFunctions,MathFunctions可以参数化
答案 5 :(得分:3)
这是我的解决方案。这是factory class的简单说明。
public Solver() {
functionList = new ArrayList<MathFunction>();
MathFunction sqrt = new MathFunction() {
@Override
public double calculate(double x) {
return Math.sqrt(x);
}
};
functionList.add(sqrt);
MathFunction inverse = new MathFunction() {
@Override
public double calculate(double x) {
return 1.0D / x;
}
};
functionList.add(inverse);
}
这个问题显示了两件事:
答案 6 :(得分:3)
好的,我将解决方案编码为我自己的问题。我的本能是构造函数中没有任何东西似乎是正确的。 functionList不是静态的,因此您需要一个实例来初始化它。它指定整数,所以我舍入到整数。反函数不是任何高级数学。
import java.util.ArrayList;
import java.util.List;
import java.lang.Math;
public class Solver {
private List<MathFunction> functionList = new ArrayList<MathFunction>();;
public Solver() {
// Complete here
}
public void initFunctionList() {
MathFunction functionSquareRoot = new MathFunction(){
@Override
public double calculate(double x) {
return (x<0 ? 0: Math.sqrt(x)); // maybe we need throw an exception here for negative numbers, but we'll just set it to 0
}};
MathFunction functionInverse = new MathFunction(){
@Override
public double calculate(double x) {
return (x!=0.0 ? 1/x : 0);
}
};
functionList.add(functionSquareRoot);
functionList.add(functionInverse);
}
public List<Double> solveAll(double x) {
List<Double> result = new ArrayList<Double>();
for (MathFunction function : this.functionList) {
result.add(new Double(function.calculate(x)));
}
return result;
}
}
public interface MathFunction {
double calculate(double x);
}
public class TestSolver {
/**
* @param args
*/
public static void main(String[] args) {
Solver s = new Solver();
s.initFunctionList();
System.out.println(s.solveAll(16.0));
}
}
我误导了构造函数可以
public Solver() {
// Complete here
MathFunction functionSquareRoot = new MathFunction(){
@Override
public double calculate(double x) {
return (x<0 ? 0: Math.sqrt(x)); // maybe we need throw an exception here for negative numbers, but we'll just set it to 0
}};
MathFunction functionInverse = new MathFunction(){
@Override
public double calculate(double x) {
return (x!=0.0 ? 1/x : 0);
}
};
functionList.add(functionSquareRoot);
functionList.add(functionInverse);
}
答案 7 :(得分:2)
package math;
import java.util.ArrayList;
import java.util.List;
public class DecoratorMath
{
interface MathFunction
{
double calculate(double x);
}
public static void main(String[] args)
{
DecoratorMath decoratorMath = new DecoratorMath();
decoratorMath.go();
}
public void go()
{
Solver solver = new Solver();
decorate(solver);
List<Double> results = solver.solveAll(02);
for (Double d :results)
{
System.out.println(d);
}
}
public void decorate(Solver solver)
{
solver.addFunction(new MathFunction()
{
@Override
public double calculate(double x)
{
return Math.sqrt(x);
}
});
solver.addFunction(new MathFunction()
{
@Override
public double calculate(double x)
{
return 1d/x;
}
});
}
class Solver
{
private List<MathFunction> mathFunctions = new ArrayList<MathFunction>();
public void addFunction(MathFunction mathFunction)
{
mathFunctions.add(mathFunction);
}
public List<Double> solveAll(double x)
{
List<Double> result = new ArrayList<Double>();
for (MathFunction function : mathFunctions)
{
result.add(new Double(function.calculate(x)));
}
return result;
}
}
}
答案 8 :(得分:0)
在构造函数中执行此操作只是一种不好的做法。无论如何,我的一体化解决方案。
import java.util.*;
import java.math.*;
//sqrt / inverse
public class Solver{
private List<MathFunction> functionList;
public interface MathFunction{
double calculate(double x);
}
class X implements MathFunction {
public double calculate(double x) {
return Math.sqrt(x);
}
}
class Y implements MathFunction {
public double calculate(double y) {
return 1/y;
}
}
public Solver(){
//here
functionList = new ArrayList<MathFunction>();
MathFunction f = (MathFunction) new X();
functionList.add(f);
MathFunction f2 = (MathFunction) new Y();
functionList.add(f2);
}
public List<Double> solveAll(double x){
List<Double> result=new ArrayList<Double>();
for (MathFunction function : this.functionList){
result.add(new Double(function.calculate(x)));
}
return result;
}
public static void main(String... args) {
System.out.println("result="+new Solver().solveAll(123));
}
}