1

我有以下基本接口:

public interface Value{

double getValue();
}

我想有几个不同的Outputter接口,它们可以根据值的具体类型来接受一个集合并输出它们,所以我可以有一个值类,它有 10 个其他重要字段,也应该输出。我知道这很好地属于访问者模式,但我担心的是:每个输出器总是会得到一个特定类型的值的列表,所以理论上我可以提供 MeanValue、StdDevValue 等类型的列表。我不是确定如何很好地设计这个,因为值是由另一个接口生成的,所以事实上,我只是持有对 Collection 的引用,我不想将它向下转换,然后在 Outputter 上调用特定的方法......

4

2 回答 2

1

访问者模式不涉及任何转换。这就是重点。

以下是 Visitorised 价值观家族的核心:

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() + ")");
    }
}

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

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

    List<MeanValue> meanValues = /* whatever */ ;
    outputter.accept(meanValues);
于 2012-12-18T12:54:15.030 回答
0

这不只是简单的多态性吗?即您希望每个具体类都能Outputter适当地实现。

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

访问者模式是为调用类和被调用类之间的中介而设计的。所以调用类调用一个方法并传递自己,被调用(访问)类回调。eg

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

并且实现可能如下所示:

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

请注意每个实现(类型)的实现有何不同Outputter

于 2012-12-18T10:00:11.020 回答