0

私のジレンマは、変数を設定してそれ自体を返すビルダー パターンに従う 1 つのメソッドを作成することですが、他のビジター実装によって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 に答える