次のスタイルで記述されたコードベースの一部があります。
// 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を使用するだけの利点があるのかと思いました。
これが私の2セントです。
ScheduledTask
、ScheduledJob
、ScheduledEvent
が表示されない、ScheduledInspection
などは、1つの分離されたSchedulable
インターフェースのみで、実装者をスケジュール可能にする必要があります。TaxSheet
という具象クラスは、大幅なオーバーホールが行われたためにSessionAwareTaxSheet
に変更される可能性があります。しかし、インターフェースITaxSheet
の名前はそれほど簡単には変更されないでしょう。ボトムライン:
インターフェイスを使用する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による貧血ドメインモデルの議論 :
ドメインオブジェクトに動作を設定することも強調する価値があります。 階層化を使用してドメインロジックを永続性などから分離するという堅固なアプローチと矛盾しないようにする必要があります とプレゼンテーションの責任。