0

我的困境在于创建一种遵循构建器模式的方法,该方法设置一个变量并返回自身,但我有一个由其他访问者实现实现并扩展Visitor的接口。BasicVisitor

此外,我有一个Visitable接口,该接口由其实现SampleVisitable并具有保留所有访问者历史记录的方法。


所以问题是我只想在访问者的历史记录中保留SampleVisitable访问者是否“重要”的完整参考,因为主机Visitor.clean()在访问者访问之前调用,这会清除上次访问的所有数据,但我想要“重要”访客的数据留在历史中。

这是我迄今为止的实施:

public interface Visitor {
    public void visit( Visitable visitable );

    public Visitor clone();

    public <V extends Visitor> V important();

    public boolean isImportant();
}

这是该SampleVisitable课程的一个片段:

public void accept( Visitor visitor ) {
    visitor.clean();
    visitor.visit( this );
    addToHistory( visitor ); // only adds if visitor.isImportant() == true
}

然后我有BasicVisitor哪个实现了该important()方法。现在我不想important()每次都重写该方法,但是通过我的实现,我必须这样做,因为如果其他访问者使用该important()方法,则会出现“无法从 BasicVisitor 转换为 [OtherVisitor]”形式的错误不覆盖它:

OtherVisitor otherVisitor = new OtherVisitor().important(); // cannot convert from BasicVisitor to OtherVisitor error.

做这个的最好方式是什么?我需要让这个特性实现一次,并且可供所有其他子类使用,而不需要它们覆盖它。谢谢!

编辑:

哇,抽象类正是我想要的!我做了更多研究,发现这篇关于接口和抽象类之间差异的帖子,我希望它可以帮助其他人寻找答案。

发布此答案后,我意识到在这种情况下我不必使用构建器模式,我可以创建一个setImportant( boolean isImportant )并且基本上可以满足我的需要,但我很高兴我还是问了,因为这就是我需要另一个设计问题。

编辑2:

important()在尝试了抽象类之后,我的主要问题仍然存在,我仍然需要重写Visitor.

伊利亚

4

2 回答 2

1

请试试这个。如果您使用一个abstract类,那么您实现的方法将可用于所有子类。

public abstract class Visitor {
    public abstract void visit( Visitable visitable );

    public abstract Visitor clone();

    public abstract <V extends Visitor> V important();

    public boolean isImportant() {
        //logic to store important visitors
    }
}
于 2012-10-26T21:10:28.813 回答
0

abstract class正如@sunleo 在他的回答中提到的那样,我能够使用 来解决这个问题,并将important()构建器函数更改为设置器setImportant( boolean isImportant )和泛型。

所以现在我有以下实现:

public abstract class Visitor<T> implements Cloneable  {
    private boolean important = false;
    private Graphable host;

    @Override
    public Visitor<T> clone() {
        try {
            return ( Visitor<T> ) super.clone();
        }
        catch( CloneNotSupportedException exception ) {
            log.info( exception, exception );        
        }
        return null;
    }

    public Graphable getHost() {
        return host;
    }

    public boolean isImportant() {
        return important;
    }

    public void setHost( Graphable host ) {
        this.host = host;
    }

    public void setImportant( boolean isImportant ) {
        important = isImportant;
    }

    public void visit( Graphable graphable ) {
        if( graphable instanceof Node ) {
            visit( ( Node ) graphable );
        }
        else if ( graphable instanceof Edge ) {
            visit( ( Edge ) graphable );
        }
    }

    public abstract void clean();

    public abstract void visit( Edge edge );

    public abstract void visit( Node node );
}

由于Visitor是可克隆的,因此可以轻松制作副本以保留在我的历史记录中。

于 2012-11-21T20:54:07.457 回答