English 中文(简体)
使用访客模式时的匿名或真实类别定义?
原标题:Anonymous or real class definition when using visitor pattern?

当你使用访客模式时,以及你需要在访客方法中找到一个变量时,如何去做?

我看到两种做法。 第一类使用匿名类别:

// need a wrapper to get the result (which is just a String)
final StringBuild result = new StringBuilder();
final String concat = "Hello ";

myObject.accept(new MyVisitor() {

    @Override
    public void visit(ClassA o)
    {
        // this concatenation is expected here because I ve simplified the example
        // normally, the concat var is a complex object (like hashtable) 
        // used to create the result variable 
        // (I know that concatenation using StringBuilder is ugly, but this is an example !)
        result.append(concat + "A");
    }

    @Override
    public void visit(ClassB o)
    {
        result.append(concat + "B");
    }
});

System.out.println(result.toString());

Pros & Cons:

  • Pros : you do not need to create a class file for this little behavior
  • Cons : I don t like the "final" keyword in this case : the anonymous class is less readable because it calls external variables and you need to use a wrapper to get the requested value (because with the keyword final, you can t reassign the variable)

另一种做法是进行外部访问:

public class MyVisitor
{
    private String result;
    private String concat;

    public MyVisitor(String concat)
    {
        this.concat = concat;
    }

    @Override
    public void visit(ClassA o)
    {
        result = concat + "A";
    }

    @Override
    public void visit(ClassB o)
    {
        result = concat + "B";
    }

    public String getResult()
    {
        return result;
    }
}

MyVisitor visitor = new MyVisitor("Hello ");
myObject.accept(visitor);
System.out.println(visitor.getResult());

Pros & Cons:

  • Pros : all variables are defined in a clean scope, you don t need a wrapper to encapsulate the requested variable
  • Cons : need an external file, the getResult() method must be call after the accept method, this is quite ugly because you need to know the function call order to correctly use the visitor

你,你在此问题上的做法是什么? 旧方法? 另一种想法?

最佳回答

这两种做法都是有效的,也是敌意的,这确实取决于你是否希望重新使用该守则。 顺便提一下,你的最后一点并不完全有效,因为你不需要外部档案来宣布一个等级。 这很可能是内部的阶级。

尽管如此,我使用访客的方式也一样:

public interface IVisitor<T extends Object> {
    public T visit(ClassA element) throws VisitorException;
    public T visit(ClassB element) throws VisitorException;
}

public interface IVisitable {
    public <T extends Object> T accept(final IVisitor<T> visitor) throws VisitorException;
}

public class MyVisitor implements IVisitor<String> {
    private String concat;

    public MyVisitor(String concat) {
        this.concat = concat;
    }

    public String visit(ClassA classA) throws VisitorException {
        return this.concat + "A";
    }

    public String visit(ClassB classB) throws VisitorException {
        return this.concat + "B";
    }
}

public class ClassA implements IVisitable {
    public <T> T accept(final IVisitor<T> visitor) throws VisitorException {
        return visitor.visit(this);
    }
}

public class ClassB implements IVisitable {
    public <T> T accept(final IVisitor<T> visitor) throws VisitorException {
        return visitor.visit(this);
    }
}

// no return value needed?
public class MyOtherVisitor implements IVisitor<Void> {
    public Void visit(ClassA classA) throws VisitorException {
        return null;
    }

    public Void visit(ClassB classB) throws VisitorException {
        return null;
    }
}

这样,被访问的物体就忽视了来访者想要与他们做些什么,但他们确实要返回他们。 你们的来访者甚至可以放弃一个例外。

我在几年前和到目前为止,都为我做了工作。

http://www.ohchr.org。 我只是这样说,质量(甚至汇编)没有得到保证。 但是,你们有这样的想法......:

问题回答

I do not see an interface being implemented in your second example, but I believe it is there. I would add to your interface (or make a sub interface) that has a getResult() method on it.

这将有助于第1和第2条。 你们不需要1个包裹,因为你可以界定<条码>植被恢复()的方法,以恢复你想要的结果。 举例说,由于<代码>植被()是您的接口的一部分,你无需知道任何职能。

我倾向于设立一个新类别,除非每一类差异只能一度使用。 在这种情形下,我将匿名。

cleaner设计的角度来看,第二种办法更可取,理由与你已经说明的相同。

在正常的TDD周期中,我将开始一个匿名的班子,并在稍后阶段将其重新定位。 然而,如果访问者仅在某一地点需要,而且其复杂性与你在实例(即没有复杂的)中提供的情况相匹配,那么我就将不得不在 所需后面另选一个班子(例如,另一个使用案例似乎增加了访问者/保险类别的复杂性)。

我建议采用第二种做法。 访问者进入其正式班级也符合文件和清洁守则的目的。 我不同意你提到这种做法的意见。 你们有一席之地,你们没有加入其中的任何内容,也不管怎样,你肯定会失败,但这并不意味着这必然是错误的。

访客模式的一个要点是允许多类访客。 如果你设立匿名课堂,你就是打破这种模式的。

页: 1 方法

public void accept(Visitor visitor) {
   visitor.visit(this);
}

由于您通过<条码>这一条/代码>进入访客,<条码>即为访问对象,访客可按照标准访问规则获取物体财产。





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签