0

私のgwt-appには、プレフィックス以外のすべてを共有する場所がいくつかあります(「editUserPlace」や「showUserPlace」など-この場合、状態はuserIdによって決定されます)私の現在の試みは、「ShowUserPlace」によって抽象「UserPlace」を拡張することです@Prefix("showUser")/ @Prefix("editUser") - ホール トークナイザー コードをコピーする必要があります (トークナイザー コードを継承することはできませんが、プレフィックスをオーバーライドすることはできません)。

https://groups.google.com/d/topic/google-web-toolkit/pghMLX27Y4Y/discussionトーマスは「PlaceHistoryMapperWithFactory」を使用することを提案しましたが、私はそれで立ち往生しています。

場所/トークナイザーごとにメソッドを提供する必要がありますか (「通常の」場所についても、独自のトークナイザーを提供します)? Abstract や拡張クラスを @WithTokenizer に追加する必要がありますか? どのように/どこで setFactory を呼び出す必要がありますか?

PlaceHistoryMapperWithFactory を使用した人はいますか (おそらく同様のユースケースで)? で、何かアドバイス?誰かが同じ問題に直面し、別の方法で解決しましたか?

4

2 に答える 2

1

そのファクトリーは動作するはずです:

class MyFactory {
   @Prefix("showUser")
   public PlaceTokenizer<ShowUserPlace> showUserPlace() {
      return new UserPlaceTokenizer<ShowUserPlace>() {
         protected ShowUserPlace createPlace(String id) {
            return new ShowUserPlace(id);
         }
      };
   }

   @Prefix("showUser")
   public PlaceTokenizer<EditUserPlace> showUserPlace() {
      return new UserPlaceTokenizer<EditUserPlace>() {
         protected EditUserPlace createPlace(String id) {
            return new EditUserPlace(id);
         }
      };
   }
}

abstract class UserPlaceTokenizer<P extends UserPlace> implements PlaceTokenizer<P> {
   public P getPlace(String token) {
      // shared logic between both places: parses ID (or whatever) from token
      return createPlace(id);
   }
   public String getToken(P place) {
      // shared logic between both places: build token out of place
      return token;
   }
   protected abstract P createPlace(String id);
}

もちろん、トークナイザーをサブクラス化してそのメソッドProvider<P>をオーバーライドする代わりに、何らかの種類をトークナイザーに挿入することもできます。createPlace

と一緒に使用できます@WithTokenizers。まったく同じ場所またはプレフィックスに対して 2 つのトークナイザーが見つかった場合、ジェネレーターはチョークします。

マッパーを呼び出しsetFactoryた直後に呼び出す必要がありGWT.create()ます (実際、重要なのは、マッパーgetPlaceまたはgetTokenメソッドへの呼び出しの前にファクトリを設定することです)。

于 2012-04-10T15:59:53.880 に答える
0

OK、ジェネリックトークナイザー(「UserPlaceTokenizer」)をいじりましたが、あきらめました:問題は、ファクトリーが具象クラスのトークナイザーを必要とするため、最初にジェネリックトークナイザーを作成しようとしたことです:

    public static class  Tokenizer<T extends UserPlace> implements PlaceTokenizer<T> {

    @Override
    public final T getPlace(final String token) {
        return (T) new UserPlace(token); //BAD
    }

    @Override
    public final String getToken(final T place) {
        return place.getToken();
    }
}

問題は、UserPlace から (T) へのキャストです。これは機能しません (UserPlace を具体的なサブクラスにキャストすることはできません)。したがって、トークナイザー インターフェイスを満たすために、このインスタンスを取得するには、どこかで「新しい ShowUserPlace(...) を返す」必要があります。長い話を長くしすぎないようにするために: 以前の解決策に戻ります: 拡張クラスはスーパークラスのコンストラクターをコピーし、単に独自のコンストラクターを呼び出す (スーパー コンストラクターを呼び出す) 個別のトークナイザーを提供します。

public class ShowUserPlace extends UserPlace {

public ShowUserPlace(String token) {
    super(token);
}

@Prefix(value = "showUser")
public static class Tokenizer implements PlaceTokenizer<ShowUserPlace> {

    @Override
    public final ShowUserPlace getPlace(final String token) {
        return new ShowUserPlace(token);
    }

    @Override
    public final String getToken(final ShowUserPlace place) {
        return place.getToken();
    }
}
}

暫定的な解決策は、インターフェイスのメソッドを提供する抽象トークナイザーでした。getPlace は抽象メソッド (T を返す) を呼び出し、具体的な実装は具体的なコンストラクター (スーパー コンストラクターのみを呼び出す) を呼び出します。最後に、このソリューションは上記のソリューションとほぼ同じ行数とコピーされたコードを持ちます:-|。

私はまだこれについて悪い気持ちを持っています - おそらく彼らはまだ「..WithFactory」を使った解決策であるか、この種のユースケースに直面するためのまったく異なる方法です。

于 2012-04-11T08:58:37.243 に答える