29

戦略パターンの使用中に問題が発生しました。タスクを作成するサービスを実装しています。このサービスは、このタスクの責任者も解決します。事務員の解決は、さまざまな方法があるため、戦略パターンを使用して行われます。ポイントは、クラークを解決するために、すべての戦略が異なるパラメーターを必要とする可能性があるということです。

例えば:

interface ClerkResolver {
    String resolveClerk(String department);
}

class DefaultClerkResolver implements ClerkResolver {

    public String resolveClerk(String department) {
        // some stuff
    }
}

class CountryClerkResolver implements ClerkResolver {

    public String resolveClerk(String department) {
        // I do not need the department name here. What I need is the country.
    }

}

問題は、責任者を解決するために、すべてのリゾルバーが異なるパラメーターに依存する可能性があることです。私にとって、これは私のコードの設計上の問題のように思えます。また、次のように、戦略で必要となる可能性のあるすべての値を保持するために、クラスをパラメーターとして使用しようとしました。

class StrategyParameter {

   private String department;
   private String country;

   public String getDepartment() ...
}

interface ClerkResolver {
    String resolveClerk(StrategyParameter strategyParameter);
}

しかし、正直なところ、ストラテジーに新しい引数や別の引数が必要になるたびにパラメーター クラスを変更する必要があるため、このソリューションには満足していません。次に、戦略の呼び出し元はすべてのパラメーターを設定する必要があります。これは、どの戦略がクラークを解決するかわからないためです。したがって、すべてのパラメーターを提供する必要があります (ただし、これはそれほど悪くはありません)。

繰り返しますが、これはコードの設計上の問題のように思えますが、より良い解決策が見つかりません。

- - 編集

このソリューションの主な問題は、タスクを作成するときです。タスク サービスは次のようになります。

class TaskService {

    private List<ClerkResolver> clerkResolvers;

    Task createTask(StrategyParamter ...) {

        // some stuff

       for(ClerkResolver clerkResolver : clerkResolvers) {
          String clerk = clerkResolver.resolveClerk(StrategyParameter...)
          ...
       }

       // some other stuff
    }

}

TaskService が使用される場合にわかるように、TaskService 自体にはこれらの情報がないため、発信者は店員を解決するために必要な情報、つまり部門名や国を提供する必要があります。

タスクを作成する必要がある場合、呼び出し元は StrategyParameter を提供する必要があります。これは、店員を解決するために必要だからです。繰り返しますが、問題は発信者がすべての情報を持っていないことです。つまり、発信者はその国の知識を持っていません。部署名しか設定できません。そのため、2 つ目のメソッドをインターフェースに追加して、ストラテジーがクラークの解決を確実に処理できるようにしました。

interface ClerkResolver {
    String resolveClerk(StrategyParameter strategyParameter);
    boolean canHandle(StrategyParameter strategyParameter);
}

繰り返しますが、この解決策は私には正しく聞こえません。

したがって、誰かがこの問題のより良い解決策を持っている場合は、それを聞いていただければ幸いです.

コメントしてくれてありがとう!

4

5 に答える 5

3

抽象化を別のレベルに移動することで問題が解決する場合があるという「SpaceTruckerの提案」が本当に気に入りました:)

しかし、元の設計がより理にかなっている場合 (仕様の感触に基づいて、あなただけが知ることができます) - IMHO は次のいずれかを行うことができます: 1) 「すべてを StrategyParameter にロードする」というアプローチを維持する 2) または、この責任をストラテジー

オプション (2) については、部門/国を推測できる共通のエンティティ (アカウント? 顧客?) があると仮定します。次に、国を検索する「CountryClerkResolver.resolveClerk(String accountId)」があります。

IMHO (1)、(2) の両方は、コンテキストに応じて正当です。すべてのパラメーター (部門 + 国) のプリロードが安価であるため、(1) がうまくいく場合があります。合成の 'StrategyParameter' をビジネスに直感的なエンティティ (アカウントなど) に置き換えることさえできます。たとえば、「部門」と「国」が別々の高価なルックアップを必要とする場合など、(2) がうまくいくことがあります。これは、複雑なパラメーターで特に注目されます。たとえば、戦略が「顧客満足度」レビューのスコアに基づいて店員を選択する場合、それは複雑な構造であり、より単純な戦略ではロードされるべきではありません。

于 2013-11-14T11:03:01.050 に答える