Поскольку я начал развиваться в стиле, основанном на тестах/поведении, я оценил способность издеваться над каждой зависимостью.
Так как насмешливые фреймворки, такие как Moq, лучше всего работают, когда говорят, чтобы издеваться над интерфейсом, теперь я реализую интерфейс практически для каждого класса, который я создаю b/c, скорее всего, мне придется издеваться над этим во время теста. Ну, а программирование на интерфейс - хорошая практика, так или иначе.
Иногда мои классы принимают зависимости от .Net-классов (например, FileSystemWatcher, DispatcherTimer). Было бы здорово в этом случае иметь интерфейс, поэтому я мог бы зависеть от IDispatcherTimer, чтобы иметь возможность передать его макет и имитировать его поведение, чтобы проверить, правильно ли реагирует моя система.
К сожалению, оба вышеупомянутых класса не реализуют такие интерфейсы, поэтому мне приходится прибегать к созданию адаптеров, которые ничего не делают, кроме как наследуют от исходного класса и соответствуют интерфейсу, который я тогда могу использовать.
Вот такой адаптер для DispatcherTimer и соответствующего интерфейса:
using System;
using System.Windows.Threading;
public interface IDispatcherTimer
{
#region Events
event EventHandler Tick;
#endregion
#region Properties
Dispatcher Dispatcher { get; }
TimeSpan Interval { get; set; }
bool IsEnabled { get; set; }
object Tag { get; set; }
#endregion
#region Public Methods
void Start();
void Stop();
#endregion
}
/// <summary>
/// Adapts the DispatcherTimer class to implement the <see cref="IDispatcherTimer"/> interface.
/// </summary>
public class DispatcherTimerAdapter : DispatcherTimer, IDispatcherTimer
{
}
Хотя это еще не конец света, интересно, почему разработчики .Net не заняли минуту, чтобы заставить их классы реализовать эти интерфейсы с самого начала. Это меня очень удивляет, так как теперь есть большой толчок для хороших практик изнутри Microsoft.
Есть ли у кого-нибудь (возможно, внутри) информация, почему это противоречие существует?