输出对象基于底层实现

时间:2012-12-18 09:56:22

标签: java design-patterns

我有以下基本界面:

public interface Value{

double getValue();
}

我希望有一些不同的Outputter接口可以根据Value的CONCRETE类型获取Collection并输出它们,所以我可以拥有一个Value类,它有10个其他重要的字段,哪个也应该输出。我知道这很适合访问者模式,但我关注的是:每个输出器总是得到一个特定类型的值的列表,所以理论上,我可以提供MeanValue,StdDevValue等类型列表。我不是确定如何设计这个很好,因为值是由另一个接口生成的,所以实际上,我只是持有对Collection的引用,我不想向下转换它然后在Outputter上调用特定的方法...

2 个答案:

答案 0 :(得分:1)

访客模式并不涉及任何投射。这就是它的重点。

这是一个访客价值家庭的核心:

interface Value {
    double getValue();
    void accept(ValueVisitor visitor);
}

interface ValueVisitor {
    public void visit(MeanValue value);
    public void visit(StdDevValue value);
}

class MeanValue implements Value {
    @Override
    public double getValue() {
        // whatever
    }

    @Override
    public void accept(ValueVisitor visitor) {
        visitor.visit(this);
    }
}

class StdDevValue implements Value {
    @Override
    public double getValue() {
        // whatever
    }

    public int getDegreesOfFreedom() {
        // here's a subclass-specific method
    }

    @Override
    public void accept(ValueVisitor visitor) {
        visitor.visit(this);
    }
}

这是输出位:

abstract class Outputter implements ValueVisitor {
    public void output(Collection<? extends Value> values) {
        for (Value value : values) {
            value.accept(this);
        }
    }
}

class PrintingOutputter extends Outputter {
    @Override
    public void visit(MeanValue value) {
        System.out.println("Mean: " + value.getValue());
    }

    @Override
    public void visit(StdDevValue value) {
        System.out.println("Std Dev: " + value.getValue() + " (" + value.getDegreesOfFreedom() + ")");
    }
}

您可以将Outputter与混合值的集合或特定类型的集合一起使用:

    List<Value> mixedValues = /* whatever */;
    outputter.accept(mixedValues);

    List<MeanValue> meanValues = /* whatever */ ;
    outputter.accept(meanValues);

答案 1 :(得分:0)

这不仅仅是简单的多态吗?即你希望每个具体的课程都适当地实施Outputter

public interface Outputter {
   String output(); // implement this...
}

访问者模式设计用于调用类和被调用类之间的中介。所以调用类调用一个方法并传递自己,而被调用(访问过的)类调用back.e.g。

public interface Outputter {
   String output(Caller c); // implement this...
}

并且实现可能如下所示:

public String output(Caller c) {
   c.doWhatever(getValue());
   c.doAnotherThing(getAnotherValue());
}

请注意Outputter

的每个实现(类型)的实现方式有何不同