web-dev-qa-db-ja.com

重複しないプロパティでさまざまな構成を処理するにはどうすればよいですか?

私はJava EEテクノロジーに基づいたプロジェクトに取り組んでいます。最初に私が達成したいこと、次に私がすでに試したことをお話ししたいと思います。

仕事:

GUIエントリを介してJEEアプリケーションで選択および編集/定義する2種類の構成を想像してみてください。 構成AシステムAとの通信用であり、構成BシステムBとの通信用です。

Config AConfig Bに等しいいくつかのプロパティを取得しましたが、プロパティ自体はいくつかの点で異なります(例:列挙)。さらに構成AおよびBそれぞれに、共通していないプロパティが追加されました。これで、アプリケーションユーザーが1つの構成(AまたはB)を入力した場合、どのタイプの構成が選択されたかを常に尋ねることなく、構成のすべての指定されたメソッド/プロパティに一般的かつ簡単な方法でアクセスできるはずです。冗長ではなく簡単な方法で、特に異なるプロパティ/メソッドにどのようにアクセスできますか?

現在の設定:

冗長なコードを減らすために、一般的な構成を定義する抽象クラスを作成したので、それを「GeneralConfiguration "」と呼びましょう。

構成AおよびB各拡張GeneralConfiguration。 「共有」プロパティごとに、GeneralConfigurationはインターフェイスを定義します。各インターフェイスは、構成タイプ(AまたはB)に応じて一般構成の可能なエントリを表す異なる列挙型によって実装されました。

私のセットアップは最適ではないと思います。では、この種のタスクをどのように処理するか、どう思いますか?

5
qecce

質問は面白いと思います。それ自体は問題ではありません。相続の悪用によるものです。非常に一般的な誤用。

なぜそう言うのですか?

冗長なコードを減らすために、一般的な構成を定義する抽象クラスを作成したので、それを「GeneralConfiguration」と呼びましょう。

これが、継承を使用する最も悪い理由の1つです。 抽象クラ​​スの下の目的は、コードの重複から私たちを救うよりもはるかに洗練されています

「共有」プロパティごとに、GeneralConfigurationはインターフェイスを定義します

ここで、実装の詳細は、抽象を意味するものに転送されています。それは抽象クラスがうまくいくことを殺し、詳細から私たちを抽象化します。

AとBに共通する唯一のことは、概念的に、両方とも構成であるということですが、ここでそれらの類似点を終了します。

どうですか?

これで、アプリケーションユーザーが1つの構成(AまたはB)を入力すると、一般的で簡単な方法でアクセスできるようになります構成のすべての指定されたメソッド/プロパティ

設計上、どちらも別のものになっています。どちらも2つの異なるコンポーネントとして設計されており、現在、継承を使用して修正しようとしています。継承はそのようには機能しません。

紙の上では、どちらもまったく同じ意味と目的を持っているかもしれませんが、そのような機能はデザインに移されていません。

「詳細」(AまたはB)から自分自身を抽象化したい場合は、構成は完全にそれらに依存しない必要があります

例:

public Configuration {
  Map<enum,Object> properties;

  public Configuration(){
        properties = new HashMap<enum,Object>();
  }

  public Object getProperty(enum propertyName){
         return properties.get(propertyName);
  }

  public void setProperty(enum propertyName, Object value){
        properties.put(propertyName, value);
  }
 }

さて、AもBもありません(そして継承は不要になります)

AとBをどのように強制しますか?

これで、抽象化に「詳細」を実装できます。たとえば、委任パターンの実装

public ConfigA {
    Configuration config;

  public ConfigA(Configuration config){
      this.config = config;
  }

 public String getA(){
       return (String)  config.getProperty(MyEnumA.A);
  }

  public void setA(String value){
      config.setProperty(MyEnumA.A,value);
  }
      ...
}

「詳細」が必要な場合は、ConfigA/ConfigBを使用します。残りはConfigurationを使用します。

注:私がabstractionと言うとき、私は抽象クラスだけを指しているのではありません。私はその概念について言及しています。

3
Laiv

Builder パターンが役立つと思います。

public class ConfigBuilder 
{
    public void SetPropertyA(string a)
    public void SetPropertyB(int b)
    public GeneralConfiguration Build()
}

UIは、ConfigBuilderオブジェクトによって公開されるメソッドと相互作用する場合があります。ユーザーがOKになると、Buildメソッドが呼び出され、ConfigAオブジェクトに設定されたプロパティに基づいてConfigBまたはConfigBuilderが作成されるかどうかが決定されます。 。

0
OnesimusUnbound