Если логика работает с интерфейсом элементами, в отличие от реализации членов, то рекомендуется написание вспомогательного метода [или метода расширения].
public IRandom
{
byte NextByte ();
}
public static class IRandomExtensions
{
// logic that acts against public interface IRandom
// may be applied to all implementations
public static int GetNextUnbiasedInteger (this IRandom random) { }
public static IEnumerable<T> Shuffle<T> (
this IRandom random,
IEnumerable<T> items) { }
}
Если бизнес-логика работает против реализации членов,
public class SomeCommand : ICommand
{
// an implementation-specific member, NOT a member
// of ICommand
public int SomeControlCount { get; set; }
}
// a method that references implementation-speciic
// details. where should this go?
public void DoSomething ()
{
SomeCommand command;
int count = command.SomeControlCount;
}
тогда, вероятно, нам следует более тесно связать это с реализующим классом. Если это достаточно распространенное явление, тогда может иметь смысл базовый класс.
Лично сложные иерархии доставляют больше хлопот, чем стоят, используйте свое собственное суждение относительно удобства обслуживания, удобочитаемости и повторного использования, и с вами все должно быть в порядке!
Надеюсь, это поможет! :)