我想引用一个枚举方法来检索算法的类,以便我可以延迟加载算法的新实例,以便在策略设计模式中使用。
在这个例子中,我使用枚举来引用计算Fibonacci数的三个不同策略类:RecursiveFibonacciGenerator
,IterativeFibonacciGenerator
和MemoizedFibonacciGenerator
(所有这些都继承自{{1} }})。
代码(生成错误的行用意图评论)如下:
FibonacciGenerator
我想知道如何使用此package com.example.strategy;
public class Fibonacci {
private enum Algorithm {
RECURSIVE (RecursiveFibonacciGenerator.class),
ITERATIVE (IterativeFibonacciGenerator.class),
MEMOIZED (MemoizedFibonacciGenerator.class);
private final Class<T> algorithmClass; // Declare class of same type as constructor
private final T instance; // Declare instance of class defined in constructor
private <T extends FibonacciGenerator> Algorithm(Class<T> algorithmClass) {
this.algorithmClass = algorithmClass;
}
public T getInstance() {
if (this.instance == null) {
this.instance = this.algorithmClass.newInstance();
}
return this.instance;
}
}
public Integer getTerm(Integer termNumber) {
profileGenerator(termNumber, Algorithm.RECURSIVE);
profileGenerator(termNumber, Algorithm.ITERATIVE);
return profileGenerator(termNumber, Algorithm.MEMOIZED);
}
private Integer profileGenerator(Integer termNumber, Algorithm algorithm) {
System.out.print("Computing term using " + algorithm.toString() + " algorithm... ");
Long startTimeMilliseconds = System.currentTimeMillis();
Integer term = algorithm.getInstance().generateTerm(termNumber);
Long endTimeMilliseconds = System.currentTimeMillis();
Long computationTimeMilliseconds = endTimeMilliseconds - startTimeMilliseconds;
System.out.println("term computed in " + computationTimeMilliseconds + " milliseconds");
}
}
构造函数来存储enum
类型的成员变量。
修改:添加完整代码以澄清意图
答案 0 :(得分:6)
public enum Algorithm {
RECURSIVE(FibonacciGenerator.RecursiveFibonacciGenerator.class),
ITERATIVE(FibonacciGenerator.IterativeFibonacciGenerator.class),
MEMOIZED(FibonacciGenerator.MemoizedFibonacciGenerator.class);
private final Class<? extends FibonacciGenerator> algorithmClass;
private <T extends FibonacciGenerator> Algorithm(Class<T> algorithmClass) {
this.algorithmClass = algorithmClass;
}
}
这样做你想要的吗?
另一种选择是使用该类的实例,但经过进一步思考后我认为这是一个坏主意。如果您打算使用该类的实例,那么为什么您首先需要枚举?
答案 1 :(得分:1)
尝试提供真实实例而不是类:
public enum Algorithm {
RECURSIVE (new RecursiveFibonacciGenerator()),
ITERATIVE (new IterativeFibonacciGenerator()),
MEMOIZED (new MemoizedFibonacciGenerator());
private <T extends FibonacciGenerator> Algorithm(T algorithm) {}
}
答案 2 :(得分:1)
Plouh是对的。你可以声明并初始化一个成员变量,就好像它是一个类而不是一个枚举:
private final FibonacciGenerator _instance;
private Algorithm(FibonacciGenerator instance) {
_instance = instance;
}
然后通过公共getFibonacciGenerator()方法返回它。请注意,如果存储实例而不是Class,则无需使用泛型。并记得将该字段声明为“最终”
答案 3 :(得分:0)
我不确定我是否理解这个问题,但如果您只是想将策略保留为成员变量:
public enum Algorithm {
RECURSIVE (RecursiveFibonacciGenerator.class),
ITERATIVE (IterativeFibonacciGenerator.class),
MEMOIZED (MemoizedFibonacciGenerator.class);
private Class<? extends FibonacciGenerator> strategy;
private Algorithm(Class<? extends FibonacciGenerator> algorithmClass) {
this.strategy = algorithmClass;
}
Class<? extends FibonacciGenerator> getStrategy() {
return strategy;
}
}
答案 4 :(得分:0)
我最终得到了以下代码:
package com.example.strategy;
public class Fibonacci {
private enum Algorithm {
UNDEFINED (null),
RECURSIVE (RecursiveFibonacciGenerator.class),
ITERATIVE (IterativeFibonacciGenerator.class),
MEMOIZED (MemoizedFibonacciGenerator.class);
private final Class<? extends FibonacciGenerator> algorithmClass;
private FibonacciGenerator instance;
private <T extends FibonacciGenerator> Algorithm(Class<T> algorithmClass) {
this.algorithmClass = algorithmClass;
}
public FibonacciGenerator getInstance() {
if (this.instance == null) {
try {
this.instance = this.algorithmClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return this.instance;
}
}
public Integer getTerm(Integer termNumber) {
return profileGenerator(termNumber, Algorithm.MEMOIZED);
}
private Integer profileGenerator(Integer termNumber, Algorithm algorithm) {
System.out.print("Computing term using " + algorithm.toString() + " algorithm... ");
Long startTimeMilliseconds = System.currentTimeMillis();
Integer term = algorithm.getInstance().generateTerm(termNumber);
Long endTimeMilliseconds = System.currentTimeMillis();
Long computationTimeMilliseconds = endTimeMilliseconds - startTimeMilliseconds;
System.out.println("term computed in " + computationTimeMilliseconds + " milliseconds");
return term;
}
}