2016-10-09 13 views
1

私は標準化されたWebサービスを使用するクライアントで作業していますが、ベンダーの1人はこれらの動作を考慮する必要があります。これを行うには、私たちがenum使用されています:従属enumのデフォルトとしてベースenumを使用

public enum ServiceProviderType { 
    FOO, BAR; 

    public ServiceProviderType checkService(String url) { 
     if (url.equals("http://www.example.com")) { 
      return ServiceProviderType.FOO; 
     } else { 
      return ServiceProviderType.BAR; 
     } 
    } 
} 

は、これらの行動の差はまた、我々はサービスから依頼内容に応じて異なるが、例えば、我々は層を要求する可能性があり、その層が赤色にしたいが、それBARを知っていますFOOサービスはRGB値を別々に表します。これを行うために、サービスの各レイヤーに必要なプロパティを格納する別の列挙型を作成しました。

public enum LayerServiceProviderType { 
    FOO("#ff0000"), 
    BAR("#ff5555"); 

    private String colour; 

    public ServiceProviderType(String colour) { 
     this.colour = colour; 
    } 

    public String getColour() { 
     return colour; 
    } 

    public ServiceProviderType checkService(String url) { 
     if (url.equals("http://www.example.com")) { 
      return ServiceProviderType.FOO 
     } else { 
      return ServiceProviderType.BAR; 
     } 
    } 
} 

これは、我々は、複数の層を処理し、同じベースの列挙型のすべてのもの誘導体としてそれらを扱いたいときを除いて正常に動作します。基本的には、Layer1ServiceProviderType.BARをLayer2ServiceProviderType.BARと同等のものとして扱いたいと考えています。しかし、列挙型をサブクラス化することはできません。そのようにしようとしても、あらゆる種類の健全な設計原則を破るようです。

私が最初に考えたのは列挙型が含まれているインタフェース持つことでした。

interface ServiceProvider { 
    ServiceProviderType {FOO, BAR}; 

    ServiceProviderType getServiceProviderType(); 

    ServiceProvider checkService(String url); 
} 

public enum LayerServiceProvider implements ServiceProvider { 
    FOO (ServiceProviderType.FOO, "#ff0000"), 
    BAR (ServiceProviderType.BAR, "#ff0000"); 

    public LayerServiceProvider(ServiceProviderType serviceProviderType, String colour) { 
     this.serviceProviderType = serviceProviderType; 
     this.colour = colour; 
    } 

    @Override 
    public ServiceProviderType getServiceProviderType() { 
     return this.serviceProviderType; 
    } 

    @Override 
    public ServiceProvider checkService(String url) { 
     if (url.equals("http://www.example.com")) { 
      return LayerServiceProviderType.FOO 
     } else { 
      return LayerServiceProviderType.BAR; 
     } 
    } 
} 

をしかし、それぞれが同じ値の範囲を保持する列挙中で列挙型を持っている私には神経が高ぶったようです。これを行うより良い方法はありますか?

+0

任意の理由は? – Andreas

+0

'colour'と他の変数はすべての' ServiceProviderType'に共通ではありません - 変数はサービスプロバイダから要求されたものに従って変更されます。共通性は列挙です。 – Michael

+0

あなたが持っている問題が本当に私には分かりません。これは、問題ドメインの仕様とモデル設計とほぼ同じくらいenumについての質問ではありません。 「うまく設計されていないAPIは、クラスを永遠に破壊する可能性があります」 - J. Blochおそらく列挙型はエレガントな方法です(戦略の列挙型は問題ですが、そうではないかもしれません)。私はあなたのプロジェクトで、どのように手助けをするかを知っているだけでは十分ではない。 – scottb

答えて

0

多分、Visitor Patternがあなたが探しているものです。

enumと一緒に使用すると、基本的にはswitch文を使用せずにenum依存ロジックを追加することができます。

例:あなただけServiceProviderType` `に` colour`を追加することができませんでした

public enum ServiceProviderType { 
    FOO { 
     @Override public <T> T apply(Action<T> action) { return action.doFoo(); } 
    }, 
    BAR { 
     @Override public <T> T apply(Action<T> action) { return action.doBar(); } 
    }; 

    public interface Action<T> { 
     T doFoo(); 
     T doBar(); 
    } 

    public abstract <T> T apply(Action<T> action); 

    public static ServiceProviderType checkService(String url) { 
     if (url.equals("http://www.example.com")) 
      return FOO; 
     return BAR; 
    } 
} 

public class LayerServiceProviderType implements ServiceProviderType.Action<String> { 
    @Override 
    public String doFoo() { 
     return "#ff0000"; 
    } 
    @Override 
    public String doBar() { 
     return "#ff0000"; 
    } 
} 

public class Main { 
    public static void main(String[] args) { 
     ServiceProviderType type = ServiceProviderType.checkService(""); 

     String colour = type.apply(new LayerServiceProviderType()); 
    } 
} 
+0

私はこのパターンが好きですが、LayerServiceProviderTypeが複数の変数を返す必要がある場合にどのように動作するのだろうかと思います。私が 'colour'変数と' name'変数(そしてもっと多くの変数)を持つ必要があるかもしれない場合など。 – Michael

+0

その場合、上の 'Layer ...'クラスを* factoryクラス*と考えることができ、問題のgettersメソッドのセットを持つオブジェクトを返します。ゲッターメソッドだけではありません。基本的には「ファクトリパターン」(https://en.wikipedia.org/wiki/Strategy_pattern)のようになり、基本的には「ファクトリ」を使用して列挙型の「戦略」を得るという行動的な方法です。 – Andreas

関連する問題