さまざまな理由で、コレクションに対する操作を抽象化するとします。
簡単にするために、コレクションの理由を説明しましょう
class Book {
public string Title { get; set; };
public string SubTitle { get; set; }
public bool IsSold { get; set; }
public DateTime SoldDate { get; set; }
public int Volums { get; set; }
}
私はBook::Title
(大文字と小文字を区別するかどうかにかかわらず)のみを検索する必要があるタイプを持っているので、抽象化を定義できます:
interface ITitleSearcher {
bool ContainsTitle(string title);
}
そして実装する
class CaseSensitiveTitleSearcher : ITitleSearcher { ... }
class NoCaseSensitiveTitleSearcher : ITitleSearcher { ... }
そしてそれを消費する
class TitleSearcherConsumer {
public TitleSearcherConsumer(ITitleSearcher searcher) { // <- ctor injection
}
}
ここまではすべてが明確であり、私が理解していることについては、インターフェイス分離の原則も遵守されています。
開発を続けると、他の要件を満たす必要があるため、次のような他のインターフェイスを定義して実装しますITitleSearcher
。
class CaseSensitiveSubTitleSearcher : ISubTitleSearcher { ... }
class SoldWithDateRangeSearcher : ISoldDateRangeSearcher { ... }
DRYに違反しないように(繰り返さないでください)、ラッパーを作成できますIEnumerable<Book>
:
class BookCollection : ITitleSearcher, ISubTitleSearcher, ISoldDateRangeSearcher
{
private readonly IEnumerable<Book> books;
public BookCollection(IEnumerable<Book> books)
{
this.books = books;
}
//...
}
TitleSearcherConsumer
のインスタンスを問題なく渡すことができるような消費者がいる場合BookCollection
。
しかし、私がこのような消費者を持っている場合:
class TitleAndSoldSearcherConsumer {
public TitleAndSoldSearcherConsumer(ITitleSearcher src1, ISoldDateRangeSearcher src2) {
}
}
BookCollection
インスタンスをTitleAndSoldSearcherConsumer
ctorに注入できません。各インターフェースの実装を渡す必要があります。
はい、他のインターフェイスのすべてのメソッドで を定義しIBookCollection
て、すべてのコンシューマーで使用できますが、そうしても ISP に違反しませんか?
ISP/SOLID と DRY を同時に近くに置くことはできますか?