web-dev-qa-db-ja.com

データ転送オブジェクトのインターフェイスを作成する必要がありますか?

データ転送オブジェクトのインターフェースを作成するのは良い考えですか、悪い考えですか?通常、オブジェクトは変更可能であると想定します。

私の例はJavaですが、同様の概念を持つ他の言語にも適用できます。

interface DataTransferObject  {
    String getName();
    void setName(String name);
}

class RealDataTransferObject  implements DataTransferObject {

    String name;
    String getName() {
        return name;
    } 
    void setName(String name) {
        this.name = name;
    }
}

もちろん、これは単純化された例であり、実際にはより多くのフィールドがあるかもしれません。

20

一般的な答えはnoです。これは、具体的な具体的な理由がない限りコードを追加してはならず、そのようなインターフェースに一般的な理由はないためです。

とはいえ、ときどき正当な理由がある可能性があります。しかし、私が見たすべてのケースで、これらのインターフェイスは部分的であり、共通のスーパークラスを提供せずに複数形で使用したい複数のクラスによって共有される1つまたはいくつかのプロパティのみをカバーしています。典型的な候補は、ある種のレジストリで使用するIdプロパティ、またはユーザーに表示するNameプロパティです。しかし、Xを含むすべてのコードを処理するコードが必要な場合に役立ちます。XSourceを含むgetXインターフェースを作成するだけです(必要な場合のみ、setX)メソッド。

しかし、すべてのプロパティを含む、すべてのモデルクラスの個別のインターフェイス?それをする正当な理由は想像もできない。悪い理由は、それを必要とする不適切に設計されたフレームワークです。エンティティEJBは、私が正しく覚えていれば、まさにそれを行いました。ありがたいことに、それらはあまりにもひどく、あまり牽引力を得られなかったため、EJB 3.0以降は非推奨です。

補足:「値オブジェクト」という用語を使用してJava Beanを簡単なゲッターとセッターのみで記述してください- 値オブジェクト のより一般的な定義と矛盾します通常は不変のIDはありません。より適切な用語は [〜#〜] dto [〜#〜] またはモデルクラスですが、後者の場合は 貧血ドメインモデル アンチパターンと見なされます。

24

インターフェースの作成は問題ありませんが、例の動作方法ではありません。あなたはインターフェースからセッターを削除する必要があり、それは大丈夫です:

interface ValueObject {
  String getName();
};

これにより、名前をデータベースからフェッチできるなど、さまざまな実装が可能になります...セッターは別のインターフェイスにある必要があります。

2
tp1

インターフェースは、インターフェースを実装するクラスとそのクライアントの間の規約を定義します。これらは、クライアントが「特定の動作を持つもの」を操作できるように、抽象化メカニズムとして使用されます。

したがって、「このインターフェースを作成して使用する必要がありますか?」という質問に対する一般的な答えは、あり:はい、クライアントに意味的に関連する(単一の)概念を関連付けることができる場合。

たとえば、Comparableは優れたインターフェイスです。これは、それらのメソッドの1つを使用して物事を比較できることを説明し、クライアントとして、比較可能なオブジェクト(たとえば、それらを並べ替えるため)の処理に興味があるためです。 。 contrario、CoolStuffは、クールなオブジェクトに特定の動作がないことを認める場合は適切なインターフェイスではありません(実際、クールなオブジェクトを処理することが理にかなっているソフトウェアを想像できます。 beCoolメソッドなどの一般的な動作)。

あなたの特定のケースでは、あなたのインターフェースは役に立たないと思います。誰が、いつ、どのように使用しますか?変更可能な値ごとにインターフェースを作成することはできません。そのため、メソッドの背後にある関連する興味深いプロパティは何かを自問してください。

必要なのが、いくつかのメソッドを介してアクセス可能なすべての変更可能な値を持つオブジェクトを処理する場合は、Java Beanの概念と、クラスに規則を強制的に適用させる方法をご覧ください。 。

2
mgoeminne

Michaelが言ったように、特別な必要がない限り、インターフェイスを追加しないでください。

テストは正当な理由の例です。実際のコラボレーターを「値オブジェクト」と呼ぶ場合は、それらを使用することをお勧めしますが、実際の単体テストの分離では、テスト用の偽のオブジェクトを作成する必要がある場合があります。この場合、インターフェースが非常に役立ちます。

2
jhewlett

このオブジェクトで将来何らかのフィールド検証を行う場合は、初期段階でそれらをカプセル化する必要があります。

1
goodfella

「値オブジェクトのインターフェース」は、アクセサーを呼び出すために使用されるものです。

アクセサーのニーズに関するさまざまなポリシーを経験しました。一部の人々は、できる限り多くのことを主張し、他の人々は、書き込むコードの量を減らすことを禁止しています。

アクセサー(または直接的な値の使用)のいくつかの根拠は次のとおりです。

  • アクセサは、値が格納される方法を後で変更できます
  • アクセサーにより、ソフトウェアをデバッグするときにアクセスログを追加できます(単一のメソッドでログ呼び出しを追加すると、すべての値の変更をキャプチャします)
  • アクセサーは、オブジェクトプログラミングとより一致し、すべての変数がメソッドによってカプセル化されます
  • アクセサーはコードの表現力を削減します(同じ結果のSLOCが増えます)
  • アクセサはいくつかのCPUを使用します

私は個人的に、アクセサーの数を減らし、後でセッター(setName)が単純な影響以上のものになると予想されるときにそれらを使用することを推奨しています。

この種類の値オブジェクトはかなり低レベルです。 2つの方向のいずれかにプッシュすることをお勧めします:(1)値オブジェクトを不変にする、つまり実際の値のように、または(2)可変性をより高いレベルのドメイン指向に上げるビジネス機能、つまりドメイン関連の機能単位の観点からインターフェースを公開する必要があります。

0
Erik Eidt