0

私はAPIを構築しています。その機能の 1 つは、いくつかのリソース分析を実行し (ドキュメント、URI、または DB を想像してください。重要ではありません) 、POJOList<Finding>がどこにあるかを返します。API から返されたすべてのデータを使用して、API から返されたデータを不変にしFindingたいのですが、クライアントの利便性のために単一のメソッドが必要です。 FindingsetUserNote(String)

その理由は、クライアントが s のリストを取得し、オブジェクト自体に独自のデータを保存するためにFinding使用しながらそれらを処理できるようにするためです。setUserNoteクライアントがFinding1 つの変数を追加するか、それをインスタンス変数としてカプセル化しExtendedFinding.someMethod() { return this.finding.someMethid(); }Finding. さらに、控えめに言っても、クライアントがAPI から取得したものから構築ExtendedFindingするのは面倒です。Findingそのため、便宜上使用できるフィールドを 1 つだけ提供する予定です。

質問:

  1. これは悪いデザインですか、それはなぜですか? 私はこれまでにこのようなことをしたことがなく、API クラスにクライアントの利便性のために任意のデータ ホルダー変数が付属しているのを見たこともありません。

  2. これは悪い設計だとしましょう。Finding を簡単に伝搬してクライアントが ExtendedFinding を構築するための適切な設計パターンは何でしょうか? 確かに、あなたは public のようなものを持つことができますがExtendedFinding(Finding) { /* copy vars one by one */ }、それはエレガントではありません

4

3 に答える 3

1

これは必ずしも悪い設計ではありません。しかし、それは珍しいように聞こえます。API を設計する際には、API の使用可能性を念頭に置くことが重要ですが、これは少し行き過ぎだと感じています。

  • これは、単一責任の原則を破るものです。クラスは、ユーザー指定のデータを表すことFindings 、コンテナーになることの両方の役割を果たします。
  • Stringユーザーを任意のオブジェクトではなくメモに制限します。たとえば、必要に応じてマップやカスタム POJO を使用することはできません。(ただし、これはジェネリックを使用して簡単に修正できます。)

より良い解決策は、クラスで メソッドequalshashCodeメソッドを定義することです。Findingこのようにして、これらのオブジェクトを へのキーとして使用できMap、ユーザーは自分のメモを API の外部に保存できます。

Finding別の解決策として、aとユーザー ノートのペアを表す新しいクラスを定義する場合があります。これは、それ以外の場合は不変のクラス内にメモを格納するよりもクリーンな「感触」を持っていますFindingが、複雑さが増すため、努力する価値がない場合があります。どのソリューションが最適かは、状況によって異なります。正解も不正解もありません。

(ちなみに、finalキーワードはクラスを不変にするわけではありません。それは、そのサブクラスを定義できないことを意味します。最終的な可変クラスを作成できます。たとえば、StringBuilder)

于 2013-03-24T00:58:36.373 に答える
1

最初の 3 番目のポイントfinalは、クラスを不変にすることは決してありません。これは、クラスを継承できないことを意味します。extendしたがって、finalクラスはできません。

interfaceあなたの主な問題として、POJO を にキャストして、基礎となる POJO ではなくそのリストを返さないのはなぜですか。次に、実際の POJO クラス パッケージを非公開にして、クライアントがキャスト バックできないようにします。

public static interface Finding {
    //all public getters

    void setUserNote();
}

static final class FindingImpl implements Finding {

    @Override
    public void setUserNote() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}
private final Collection<FindingImpl> findingImpls = new ArrayList<>();

public Collection<Finding> getFindings() {
    final Collection<Finding> findings = new ArrayList<>();
    for (final FindingImpl fi : findingImpls) {
        findings.add(fi);
    }
    return findings;
}
于 2013-03-24T00:58:47.757 に答える
0

よくわかりません。あなたが不変であると考える調査結果を私に返した場合、そのオブジェクトに一度だけメモを挿入できることは、私にとってどのように意味がありますか? 他の人にも同じ調査結果が示される可能性があると推測されますよね?

ここでの正解は、別のクラスが必要だということです: コメント投稿者の ID、調査結果の ID、およびタイムスタンプを持つ FindingComment です。

クラスを拡張してコメントをグロムにするというあなたの本能は確かに正しいです!

于 2013-03-24T02:47:28.103 に答える