2

2つのインターフェースと1つの動作クラスがあるとしましょう。

public interface Creable {
    public boolean belongsToSystem();
    public List<Creable> getCreatedItems();
}

public interface HasDependencies {
    public void createDependencies();
    public void generateDependents();
}

public class CreableBehavior {
    private Creable creableObject;
    public CreableBehavior(Creable creableObject) {
         this.creableObject = creableObject;
    }

    public boolean hasBeenCreated() {
        return !creableObject.belongsToSystem() && !creableObject.getCreatedItems().contains(createdObject);
    }

そして、このコードは次のとおりです。

Creable includedTab = new AdempiereTab(getIncluded_Tab_ID(),
                creableElements);
if (!new CreableBehavior(includedTab).hasBeenCreated) {
    includedTab.createDependencies();
    includedTab.getCreatedItems().add(includedTab);
    includedTab.generateDependents();
}

AdempiereTabは、CreableとHasDependenciesの両方を実装しています。問題は、CreableとHasDependenciesの両方のインターフェースを使用する必要があることです。
このようにキャストする必要があります:

if (!new CreableBehavior(includedTab).hasBeenCreated) {
    ((AdempiereTab)includedTab).createDependencies();
    includedTab.getCreatedItems().add(includedTab);
    ((AdempiereTab)includedTab).generateDependents();
}

または、両方のインターフェイスを拡張する新しいインターフェイスCreableWithDependenciesを作成し、代わりにそのインターフェイスを使用する必要がありますか?

ありがとう。

編集:回答済み、実装タイプに依存したくないので、インターフェイスを拡張する必要があります。それらを組み合わせると、同じコードで多くのタイプを使用できるようになります。

4

3 に答える 3

2

2つの設計力が働いています。インターフェースを可能な限り小さく保つことと、インターフェースの数を最小限に抑えることです。一般に、大きなインターフェイスは後でリファクタリングするのにより問題があります。

インターフェイスがシステム全体ですでに使用されている場合は、クライアントコードを個別のメソッドまたはクラスに分割するか、CreableHasDependencies両方のインターフェイスを拡張するインターフェイスを作成するか、クラスタイプを直接使用することができます。

インターフェイスを初めて使用する場合は、インターフェイスがクライアントコードに属しているため、インターフェイスを組み合わせます。

于 2012-07-25T13:49:39.653 に答える
2

AdempiereTabを作成するコードスニペットの表示のみに基づいた私の最初の考えは、その変数タイプをCreableではなくAdempierTabとして宣言するだけでよいということでした。抽象型Creableを使用する必要はありません。これは、これがインターフェイスメソッドを実行する型であることをすでに認識しているためです。

第二に、Creableが(前のコード行から)AdempiereTabであることを知っていても、例外を回避するために、キャストする前にinstanceofを使用してチェックすることをお勧めします。これは、「includedTab」をAdempiereTabとして宣言するだけでよいという事実を実証しています。

さらに、しかし、あなたのアプリケーションの文脈をあまり知らずに、私はインターフェースHasDependenciesに疑問を投げかけます。純粋に名前に基づいているので、それ自体が方法のようです。しかし、それが公開する動作は混乱しているようです。作成と生成の両方でvoidが返されます。私にとって、これは、このインターフェースがよく考えられていて、おそらくより明確なものに作り直す必要があるかどうかという疑問を投げかけるだけです。これは、現在直面している問題を回避するのに役立つ場合があります。

于 2012-07-25T13:53:37.463 に答える
0

または、次のようなことを行うことができます。

AdempiereTab includedTab = new AdempiereTab(getIncluded_Tab_ID(),
                creableElements);
if (!new CreableBehavior(includedTab).hasBeenCreated) {
    includedTab.createDependencies();
    creableElements.getCreatedItems.add(includedTab);
    includedTab.generateDependents();
}

AdempiereTab両方のインターフェースを実装しているのでAdempiereTabCreableBehavior'sコンストラクターに渡すことができます。

于 2012-07-25T13:44:24.863 に答える