title: How (or, if) to avoid cross-dependencies between classes
body: <p>I'm working on an exercise that involves implementing a simple card game (similar to rummy).</p>
  
  <p>So, I have a <code>Card</code> class which has <code>suit</code> and <code>rank</code> members. I have a <code>Cards</code> class which inherits from <code>List&lt;Card&gt;</code>.</p>
  
  <p>I'm writing code to check for winning conditions, which involves finding whether a player's hand contains runs (9H, 10H, JH, QH) or matching sets (2H, 2D, 2C).</p>
  
  <p>So, I'm implementing code on the <code>Cards</code> class to find any runs or sets contained in the collection. The first step for finding a run (at least, the way I'm implementing it) is to sort by suit, then by rank. And then, the first step to finding matching sets is to sort by rank, then by suit (I guess sorting by suit is not strictly needed, but I'm implementing it that way to make sure the cards always sort in a predictable order).</p>
  
  <p>So, I have created a class <code>CardComparerSuitRank : IComparer&lt;Card&gt;</code> and another class <code>CardComparerRankSuit : IComparer&lt;Card&gt;</code>. Then, if you call <code>myCardsInstance.FindLargestSet()</code>, the first thing the method does is create a shallow copy of the <code>Cards</code> instance called <code>cardsToSearch</code> and call <code>cardsToSearch.Sort(CardComparerRankSuit.Default)</code>, and then it iterates through <code>cardsToSearch</code> and notes the largest matching set.</p>
  
  <p>While I was working on this, though, I realized that this was creating an implicit dependency on <code>CardComparerRankSuit</code> for my <code>Cards</code> class. To provide all of its exposed functionality, <code>Cards</code> depends on the comparer class. This seems bad since, in my mind, a class ought to encapsulate all the functionality it exposes (or at least, if it depends on another class, that dependency should be explicit like through inheritance).</p>
  
  <p>So, my question is, what pattern do I use to avoid this scenario? I bet there's a way to write the class so that this functionality is fully encapsulated, but that seems like it leads to writing an enormous, hard-to-read class definition. Or can I, through some combination of class/interface inheritance, divvy the functionality up more sensibly among multiple source files? Or should I just lighten up and stick with the pattern I described above and not worry so much?</p>