所有子类的一个构建器方法实现(泛型?)

时间:2012-10-26 21:04:07

标签: java generics visitor-pattern builder-pattern

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

此外,我有一个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()方法,但是我必须使用我的实现,因为任何其他访问者都会遇到“无法从BasicVisitor转换为[OtherVisitor]”形式的错误如果他们使用important()方法而不覆盖它:

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

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

修改:

哇,抽象类正是我想要的!我做了一些研究并在differences between interfaces and abstract classes上发现了这篇文章,我希望它可以帮助其他人寻找答案。

在我发布这个答案之后,我意识到在这种情况下我不必使用构建器模式,我本来可以创建一个setImportant( boolean isImportant )并且基本上会有我需要的东西,但我很高兴我无论如何问,因为这是我需要的另一个设计问题。

编辑2:

在尝试抽象类之后,我的主要问题仍然存在,我仍然必须为important()的每个子类覆盖Visitor方法。

伊利亚安德

2 个答案:

答案 0 :(得分: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
    }
}

答案 1 :(得分:0)

我能够使用abstract class解决此问题,正如@sunleo在答案中提到的那样,并将important()构建器函数更改为setter 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可以克隆,因此可以轻松地在我的历史记录中制作保留副本。