3

私は次のことになっているコンポーネントに取り組んでいます:

  1. 外部の計算コンポーネントからデータ(アイテムのコレクション)を受け取ります。私は、各リクエストの入力で約100〜1Kのアイテムを期待しています。

  2. データを検証し、欠落している場合はいくつかの属性を計算します

  3. データを永続化する

アイテムは約10種類あります。アイテムをモデル化するために継承を使用します。共通の属性と計算を備えた基本アイテムクラスと、タイプ固有の問題を実装するサブクラスがあります。次の例と同様です。

public abstract class BaseItem {
    String name;
    boolean valid = true;

    public void postCalucate() {
        //common calculation
                    valid = valid && (name != null);
    }
}

public   class ItemA extends BaseItem {
    BigDecimal value;

    @Override
    public void postCalucate() {
        //some A specific calculations                        
        super.postCalucate();
    }
}

public   class ItemA1 extends ItemA {
    BigDecimal extraValue;

    @Override
    public void postCalucate() {
        //some A1 subtype specific calculations
               valid = isA1ItemValid();
        super.postCalucate();
    }
}

public   class ItemB extends BaseItem {
    Integer size;

    @Override
    public void postCalucate() {
        //some B specific calculations
        super.postCalucate();
    }
}

私の仕事をするためのより良い方法/パターンはありますか?何かアドバイスはありますか?

4

3 に答える 3

1

一般的なアドバイスは、継承の過剰使用を避けることですが、これは過剰使用の場合ではありません。したがって、このアプローチを進めてください。

それとは別に:あなたのコードはカプセル化に関する問題を示しています。これらの非プライベートフィールドをすべて持つべきではありません。注意:パッケージの可視性はまったくありません(パッケージ全体とすべてのサブクラスに表示されます)フィールドをプライベートにします。

于 2012-10-30T19:40:52.090 に答える
1

使用しようとしているパターンはかなり健全です。一般的に、クラスの代わりにインターフェースを使用することをお勧めしますBaseItem。これは、それほど一般的な機能が含まれていない可能性があるためです。

一般に、ほとんどの人は、クラスが実装するインターフェースを定義することを推奨しているようです。どうしてもAbstractClassで共通のコードを共有したい場合は、インターフェイスを実装するクラスをお勧めします。このパターンは、将来、拡張性と柔軟性を高めるのに役立つからです。

そのため、最初にアイテムが自分にとって何であるかを定義することから始めます。私にとって、アイテムはユースケースでは3つのもののようです。1つは、postCalculate()すべてのアイテムで呼び出されるメソッドを定義する必要があることです。isValid()第二に、それはメソッドを提供しなければなりません。そして第三に、それはまたgetName()方法を提供するべきです。

public interface Item {
    void postCalucate();
    boolean isValid();
    String getName();
}

次に、Abstractクラスの実装を開始します。これは、すべてのアイテム間でコードベースを共有することが本当に必要な場合にのみ行ってください。

public abstract class BaseItem implements Item {
    String name;
    boolean valid = true;

    public void postCalucate() {
        //common calculation
        valid = valid && (name != null);
    }

    public boolean isValid() { 
        return valid; 
    }

    public String getName() {
        return name;
    }
}

BaseItem.postCalculate()がすべてのアイテムに対して実行する必要があるものである場合、これはそれを実行するための良い方法です。完全に確信が持てない場合は、代わりに、アイテムに対してこの一般的な計算を実行し、メソッドによって呼び出される、Helperまたはクラスのどこかにメソッドを定義することをお勧めします。ToolpostCalculate()

public class ItemTools {
    public static boolean meetsRequirements(Item item) {
        return item.isValid && item.getName() != null;
    } 
}

BaseItemこれは、多くの人が主張するように、要件が時間の経過とともに変化する可能性があるため、より簡単な時間を提供します。

そこに行くルートに関係なく、実際のアイテムを定義する必要があります。

public   class ItemA extends BaseItem {
    BigDecimal value;

    @Override
    public void postCalucate() {
        //some A specific calculations                        
        super.postCalucate();
    }
}
于 2012-10-30T19:54:19.477 に答える
0

先験的に、あなたの提案は合理的なようです。

ただし、確かに、オブジェクトのライフサイクルのすべてのイベントを確認する必要があります。

  • インスタンス化
  • 使用、読む
  • コラボレーション
  • 永続性
  • ..。
于 2012-10-30T19:41:58.580 に答える