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


19

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

私の例は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;
    }
}

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

回答:


24

一般的な答えはnoです。特定の具体的な理由がない限りコードを追加しないでください。また、このようなインターフェイスの一般的な理由はありません。

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

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

サイドノート:「値オブジェクト」という用語を使用してJava Beanを簡単なゲッターとセッターのみで記述することは避けてください- 通常は不変であるIDのないものとしての値オブジェクトのより一般的な定義と競合します。より良い用語はDTOまたはモデルクラスです。ただし、後者の場合、貧血ドメインモデルはアンチパターンと見なされることに注意してください。


3
「貧血領域モデルはアンチパターンと見なされます」-PEAAで、何十年もその方法で「非常にうまく」働いた人々を知っていることを認めるMartin Fowlerによる。したがって、私は、アンチパターンではなく、よりファウラーのように働くのではないことを提案します。それにもかかわらず、良い答え、+ 1。
pdr

4
@pdr:ファウラーはこの用語を作り出したかもしれませんが、彼をアンチパターンと見なしているのは決して彼だけではありません。OOを実際に理解している人は、ドメイン固有のロジックをドメインモデルに入れないことをお勧めだとは思いません。
マイケルボルグワード

用語修正のおかげで、DTOは昨夜探していた言葉でしたが、私の人生を思い出せませんでした。周りの名前を変更することで、物事はデザイン的に賢くなりました。
アルキメデストラハノ

@pdrそれを置く最良の方法は、オブジェクト指向プログラミングのコンテキストにおけるアンチパターンであることだと思います。それが完全に素晴らしい他の多くのパラダイムがあり、オブジェクト指向言語でそのようにうまく動作させることさえできます(特にオブジェクト指向ではないでしょう)。
ダニエルB

3
@MichaelBorgwardt:同意します、彼はその中に一人ではありません。しかし、反対する人もいません。「貧血領域モデルはアンチパターンとみなされる人もいる」と言っていたら、私は何も言わなかったでしょう。率直に言って、とにかく最後の段落がなければ、あなたの答え全体が良くなると思います。前半はより良いコメントをしたでしょう。後半はこの質問に何も提供しません。
-pdr

2

インターフェースの作成は問題ありませんが、サンプルの動作方法は異なります。インターフェイスからセッターを削除する必要がありますが、問題ありません。

interface ValueObject {
  String getName();
};

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


2

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

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

たとえば、Comparableは優れたインターフェイスです。メソッドの1つのおかげで物事を比較できることを説明しているため、クライアントとして、比較可能なオブジェクト(ソートなど)の処理に興味があります。contrarioは、CoolStuffは彼らのような一般的な振る舞いがあるので良いインタフェースではありませんあなたはクールなオブジェクトは、特定の行動を持っていない認める場合(実際には、あなたが想像できるクールなオブジェクトを扱うているソフトウェアは、理にかなってbeCoolを方法)。

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

いくつかのメソッドを介してすべての可変値にアクセスできるオブジェクトを処理する場合は、Java Beanの概念と、クラスに規則を適用させる方法を確認してください。


2

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

テストは正当な理由の例です。実際のコラボレーターを呼び出すとき、それらが単に「値オブジェクト」である場合、実際のコラボレーターを使用することを好みますが、真の単体テスト分離のために、テスト用の偽オブジェクトを作成する必要があります。


1
長い間、モックフレームワークを使用するためのインターフェイスは必要ありませんでした。
マイケルボルグ

モンキーパッチを提唱しているようですね。私はC#でMolesを使ってその道を歩んできましたが、それほどきれいではありません。可能であれば、共同編集者を渡すことをお勧めします。
ジューレット

1
私がMockitoとeasyMockを使用する2つのモックフレームワークは、それらを不変にしたときにfinalクラスをモックできません。
アルキメデストラハノ

1

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


0

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

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

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

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

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


0

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.