2

例を挙げて説明します。私の GWT プロジェクトには、ユーザーが会社を追加、編集、削除、選択、および一覧表示できる Company モジュールがあります。

これらのうち、追加、編集、および削除操作は、ユーザーを CompanyList ページに戻します。したがって、3 つの異なるイベントCompanyAddedEvent, CompanyUpdatedEvent and CompanyDeletedEvent(およびそれぞれのイベント ハンドラー) を持つことは、機能にまったく違いがないため、やり過ぎのように思えます。

1 つのイベントで 3 つの操作を管理してもよろしいですか? 私が思う1つの選択肢は、のようなイベントを使用することCompanyListInvokedEventです。ただし、どこかで適切ではないと思うのは、イベントが実際に呼び出されているリストではなく、会社が追加/更新/削除されていることです。

モジュールが 1 つだけだったら、3 つの個別のイベントでタスクを完了できたはずです。しかし、そのような他の 10 のモジュールは、このジレンマに直面しています。これは、10x3 = 30 のイベント クラスとそれぞれの 30 のハンドラを意味します。その数は、私が再考するのに十分な数です。これに対する良い解決策は何ですか?

アップデート -

@ColinAlworth の回答により、愚かなソリューションの代わりに Generics を簡単に使用できることに気付きました。次のコードは、エンティティが更新されるたびに発生するイベント EntityUpdatedEvent を表します。

イベントハンドラクラス -

public class EntityUpdatedEvent<T> extends GwtEvent<EntityUpdatedEventHandler<T>>{

    private Type<EntityUpdatedEventHandler<T>> type;
    private final String statusMessage;

    public EntityUpdatedEvent(Type<EntityUpdatedEventHandler<T>> type, String statusMessage) {
        this.statusMessage = statusMessage;
        this.type = type;
    }

    public String getStatusMessage() {
        return this.statusMessage;
    }

    @Override
    public com.google.gwt.event.shared.GwtEvent.Type<EntityUpdatedEventHandler<T>> getAssociatedType() {
        return this.type;
    }

    @Override
    protected void dispatch(EntityUpdatedEventHandler<T> handler) {
        handler.onEventRaised(this);
    }
}

イベント ハンドラー インターフェイス -

public interface EntityUpdatedEventHandler<T> extends EventHandler {
    void onEventRaised(EntityUpdatedEvent<T> event);
}

イベントバスへのハンドラーの追加 -

eventBus.addHandler(CompanyEventHandlerTypes.CompanyUpdated, new EntityUpdatedEventHandler<Company>() {

    @Override
    public void onEventRaised(EntityUpdatedEvent<Company> event) {
        History.newItem(CompanyToken.CompanyList.name());
        Presenter presenter = new CompanyListPresenter(serviceBundle, eventBus, new CompanyListView(), event.getStatusMessage());
        presenter.go(container);
    }
});

同様に、他に 2 つの Added および Deleted ジェネリック イベントがあるため、イベント関連のコードベースから冗長性が完全に排除されます。

このソリューションに関する提案はありますか?

PS >このディスカッションでは、この問題についてより多くの洞察が得られます。

4

1 に答える 1

4

この質問に答えるために、まず、この同じ種類の問題について別の考え方を提示しましょう。イベントの代わりに、メソッドを使用します。

私の階層化されたアプリケーションでは、2 つのモジュールがインターフェイスを介して通信します (これらのメソッドは allvoidであるため、イベントに似ていることに注意してください。呼び出し元は応答を期待していません)。

package com.acme.project;

public interface CompanyServiceInteface {
  public void addCompany(CompanyDto company) throws AcmeBusinessLogicException;

  public void updateCompany(CompanyDto company) throws AcmeBusinessLogicException;

  public void deleteCompany(CompanyDto company) throws AcmeBusinessLogicException;
}

これは私にはやり過ぎのように思えます。この API のサイズを 1 つのメソッドに縮小し、enum 引数を追加してこれを簡素化しないのはなぜですか。このようにして、別の実装をビルドするか、単体テストでこれをモックする必要がある場合、ビルドするメソッドは 3 つではなく 1 つだけです。これは、アプリケーションの残りの部分を作成するときに、明らかに過剰になりObjectServiceInterface.modify(Object someDto, OperationEnum invocation);ます。10 個のモジュールすべてに対して機能しないのはなぜでしょうか?


1 つの答えは、1 つの実装を大幅に変更したいが、他の実装は変更したくないということです。これを 1 つのメソッドに減らしたので、すべてがその switch ケース内に属します。もう 1 つの理由は、このように単純化すると、さらに単純化する傾向があることです。おそらく、組み合わせcreateupdate1 つの方法にします。これが完了すると、すべてのコールサイトは、特定の 1 つだけではなく、そのメソッドのコントラクトのすべての可能な詳細を満たすようにする必要があります。

これらのイベントのレシーバーが単純であり、今後もそうである場合、考えられるすべてのユース ケースに対して明らかに十分に汎用的である単一の ModelModifiedEvent を持たない正当な理由はないかもしれません。おそらく ID をラップして、すべてのクライアント モジュールがそれらのそのオブジェクトのビュー。1 種類のイベントのみが重要な将来のユースケースが発生した場合、イベントを変更する必要があり、イベントを作成するすべてのサイトがこの新しいフィールドに適切に入力されるようにする必要があります。

Javaショップは通常、Javaが最も美しい言語であるため、または開発者を作成または検索するのに最も簡単な言語であるため、Javaを使用しませんが、メンテナンスとリファクタリングが比較的簡単であるためです。API を設計するときは、将来のニーズを考慮することが重要ですが、現在の API を変更するために何が必要かについても考慮する必要があります。IDE には、特定のメソッドまたはコンストラクターのすべての呼び出しを見つけるためのショートカット キーがほぼ確実にあり、次のことが可能になります。それが使用されているすべての場所を簡単に見つけて更新します。そのため、他にどのようなユース ケースが予想されるか、およびコードベースの残りの部分をどれだけ簡単に更新できるかを検討してください。

最後に、ジェネリックについて忘れないでください。上記の例では、単純化するためにおそらく DtoServiceInterface を作成して、3 つのメソッドを持つ 1 つのインターフェイスを宣言し、それを実装して必要に応じて参照するだけにします。同様に、3 つの型の 1 つのセットGwtEvent(*Handlerインターフェイスと場合によってHas*Handlersはそれも) を作成できますが、可能なすべての型に対してそれらをジェネリックに保ちます。ここで例として考えてみcom.google.gwt.event.logical.shared.SelectionEvent<T>てください - あなたのケースでは、ハンドラーが処理しているイベントのタイプをチェックできるようにモデルオブジェクトタイプをパラメーターにしたいでしょう (ジェネリックは Java で消去されることに注意してください)、またはEventBusそれぞれのソースから 1 つをソースします。モデルタイプ。

于 2013-03-23T18:32:39.193 に答える