我的问题如下:
我们有一个内部使用
的算法这将成为Java中的框架。 要解决实际问题,需要提供具体的实现 Expression和Manipulator以及Algorithm类将完成剩下的工作。
假设我们需要一个ProblemExpression和一个ProblemManipulator 针对特定问题。
ProblemExpression可能包含很多新字段, 可以由ProblemManipulator使用。
现在,我只能想到两种编写干净代码的方法:
但我觉得这不是我应该这样做的方式。 还有其他建议吗?
提前问候并感谢,
Xaero。
答案 0 :(得分:5)
听起来你应该使用Generic。像
interface Manipulator<E extends Expression> {
public void manipulate(E expression);
}
class ProblemManipulator implements Manipulator<ProblemExpression> {
public void manipulate(ProblemExpression expression) {
// expression is a ProblemExpression
}
}
答案 1 :(得分:1)
由于“问题”是一个不同的问题,它可以是一个扩展表达式的接口:
interface IProblemExpr extends Expression
{ //additional methods
}
class ProblemExpression implements IProbExpr
{
}
class ProblemManipulator()
{
ProblemManipulator(IProblemExpr expr)
{
..
}
}
答案 2 :(得分:0)
如果可以公开访问ProblemExpresions和ProblemManipulator,那么泛型是不够的。 起初我认为某种工厂框架会起作用。 即,表达式需要能够创建操纵器,反之亦然。
例如,问题操纵者是ProblemExpressions的私有内部类 - 从Expression#createManipulator(...)获得。
然而,这并没有完全解决这个问题......最后,如果允许算法“保持对Expression和Manipulator的引用”,并且可以获得不同的无关实现,那么算法实现总是可以(如果写得不正确)最终为给定的表达式调用错误的操纵器 - 在编译时无法完成任何操作以防止此运行时错误,因为可以使用任何表达式调用所有操纵器。
因此,在我看来,操纵器(或表达式)的调用必须“通过”表达式(或相反的操纵器),从而确保为给定的表达式调用正确的操纵器。
即表达式需要'manipulate()'方法,该方法委托给相应的操纵器。
答案 3 :(得分:0)
我研究了仿制药的工作方式,并提出了以下解决方案:
首先,我创建了两个类,一个用于表达式,另一个用于操纵器:
public class ObjectExpression { }
public class ObjectManipulator <E extends ObjectExpression> {
public void calculate(Set<E> objects) {
... // Do something
}
}
接下来,我创建了一个Algorithm类,它是通用的。 需要两个课程:
一些表达
操纵此类型对象的东西
我们得到:
public class Algorithm <F extends ObjectExpression, E extends ObjectManipulator<F>> {
E om;
public Algorithm( E om ) {
this.om = om;
}
public void run(Set<F> objects) {
om.calculate(objects);
}
}
然后,我为String case创建了一个实现: 我们需要一个表达式和一个操纵器
public class StringExpression extends ObjectExpression {
}
public class StringManipulator extends ObjectManipulator<StringExpression> {
@Override
public void calculate(Set<StringExpression> objects) {
// Do String stuff
}
}
然后,我们可以按如下方式运行算法:
Algorithm<ObjectExpression, ObjectManipulator<ObjectExpression>> algo1 = new Algorithm<ObjectExpression, ObjectManipulator<ObjectExpression>>(manipo);
Set<ObjectExpression> objects = new HashSet<ObjectExpression>();
... // fill set
algo1.run(objects);
对于Strings:
StringManipulator manips = new StringManipulator();
Algorithm<StringExpression, StringManipulator> algo2 = new Algorithm<StringExpression, StringManipulator>(manips);
Set<StringExpression> strings = new HashSet<StringExpression>();
... // fill set
algo2.run(strings);
对我来说,这似乎是一个优雅的解决方案。 你怎么看? 任何替代/改进?