データ指向インターフェースへのプログラミング


9

次のスタイルで記述されたコードベースの一部があります。

// IScheduledTask.cs
public interface IScheduledTask
{
    string TaskName { get; set; }
    int TaskPriority { get; set; }
    List<IScheduledTask> Subtasks { get; set; }
    // ... several more properties in this vein
}

// ScheduledTaskImpl.cs
public class ScheduledTaskImpl : IScheduledTask
{
    public string TaskName { get; set; }
    public int TaskPriority { get; set; }
    public List<IScheduledTask> Subtasks { get; set; }
    // ... several more properties in this vein, 
    // perhaps a constructor or two for convenience.
}

つまり、動作のない一連のプロパティのみを指定する多数のインターフェイスがあり、それぞれに自動プロパティでこれらを実装する対応する単一の実装があります。コードはかなり年長の誰か(私よりもはるかに年上)によって書かれており、このインターフェースの使用とは別に、合理的な手続き型コードです。他の誰かがこのスタイルに遭遇したり使用したりしていないか、インターフェイスなしでどこでも具象DTOを使用するだけの利点があるかどうか疑問に思っていました。


1
私がこれを行った理由の1つはCOMの互換性のためですが、ここではそれが理由ではないようです。
マイクがモニカをサポート

@マイク興味深い、私はCOMを使用したことがなく、ここでは使用されていません。コードのこのセクションの作成者に、COMを使用する予定か、それとも何かを使用する予定かを尋ねます。
2016年

私の推測では、彼は比較的近い将来にこれらのプロパティの少なくとも1つを非自動化する予定であり、このボイラープレートを最初に書き出すことは、後で手間を省くために慣れている習慣だと思います。 C#の男ではないので、私が言えることはこれだけです。
Ixrec

6
私見それは、実装ではなくインターフェイスへコードの過度の執着と誤用です。重要な説明は、唯一の実装です。インターフェースのポイントはポリモーフィズムですが、プロパティのみのクラスは、単に異なる値を持つという意味でポリモーフィックです。振る舞い-メソッド-を使用しても、単一の実装が与えられても意味がありません。このナンセンスは私たちのコードベース全体にあり、せいぜいそれはメンテナンスを妨げます。なぜ、何を、どこに質問するのに時間がかかりすぎます。なぜ彼らはそれをしたのか、私には見えないデザイン、そして他の実装はどこにあるのですか?
レーダーボブ2016年

2
前のコメントのほとんどは、時期尚早な抽象化の単一の実装「コード臭い」に行きます。ただし、貧血ドメインモデル「コードのにおい」もここにあります。以下を
Erik Eidt

回答:


5

これが私の2セントです。

  • DTOが少なくとも少しの動作をすることは決してないでしょう。ですから私にとっては、将来的に動作するかもしれないし、しないかもしれないオブジェクトがあります。
  • 非常に多くの唯一の-実装クラスを持っていることの1つの原因は、設計の欠如であることを確認するために失敗し、たとえば、ScheduledTaskScheduledJobScheduledEventScheduledInspection、など、一つだけを分離する必要がありますSchedulable任意の実装のスケジュールを作成するインタフェース。
  • 最初にインターフェースを作成することは非常に良い習慣であり、必要なものについての洞察を提供します。多くのインターフェースは、まったく実装されていないことから始まります。次に、誰かが1つの実装を作成し、その実装があります。2番目のポイントで言及したことを回避すると、単一の実装の状態は一時的なものになります。一部のインターフェースが2分の3の実装を決して持たないことを事前にどのように知っていますか?
  • よく考えられたインターフェースに付ける名前は、将来変更されない傾向があるため、そのインターフェースへの依存関係は影響を受けません。一方、具象クラスは、実装方法で重要な何かが変更されると名前が変更される傾向があります。たとえば、大幅なオーバーホールが行われたために名前TaxSheetが付けられた具象クラスがに変更される可能性SessionAwareTaxSheetがありますが、インターフェイスのITaxSheet名前はおそらくそれほど簡単には変更されません。

結論:

  • 優れた設計プラクティスはDTOにも適用されます。
  • DTOは、将来的に少し動作を追加できます。
  • すべてのインターフェースは、1つの実装のみから始まります。
  • 一方、1つのインターフェイス、1つのクラスのコンボが多すぎる場合は、デザインの不足が指摘される可能性があります。あなたの関心事は正当化されるかもしれません

4
私はあなたの答えに賛成しましたが、2番目の箇条書きは、すべてのクラスが対応するインターフェイスを自動的に持つ必要があることを意味します。2番目の実装がある可能性のあるオフチャンスでインターフェイスを作成すると、インターフェイスが急増し、YAGNIが発生します。
Robert Harvey

1

インターフェイスを使用するDTOで見た特定の問題は、これが可能になることです。

public interface ISomeDTO { string SomeProperty { get; set; }}

public class SomeDTO : ISomeDTO
{
    public string SomeProperty { get; set; }
    string ISomeDTO.SomeProperty { get { /* different behavior */ } set { SomeProperty = value; } }
}

このパターンが、いくつかの重要な動作を実装するための迅速で汚いハックとして適用されているのを見てきました。これにより、コードが非常に混乱する可能性があります。

SomeDTO a = GetSomeDTO();
ISomeDTO ia = a;
Assert.IsTrue(a.SomeProperty == ia.SomeProperty); // assert fails!

これを維持することは困難であり、もつれたりリファクタリングしようとすると混乱します。IMO、DTOに行動を追加すると、単一責任の原則に違反します。DTOの目的は、永続化フレームワークによって永続化および入力できる形式でデータを表すことです。

DTOはドメインモデルではありません。DTOが貧血であるかどうかを心配する必要はありません。引用すると貧血のドメインモデルのMartin Fowler氏の議論を

ドメインオブジェクトに動作を設定することは、ドメインロジックを永続化やプレゼンテーションの責任などから分離するためにレイヤーを使用するという確固たるアプローチと矛盾しないことも強調する価値があります。

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