I have a class that I'm trying to determine a good name for. I don't know if this concept comes up a lot in programming or not, but I'm wondering if I can get some suggestions for a good name for the class.
Basically, this is how the class functions:
- The first time its
Get()
method is called, it returns valueA
. - Every subsequent time, it returns value
B
. - If enough time has passed (provided), return value
A
one time, then revert back to sending 'B'. Repeat ad finitum.
Is there any name for something that functions like this? It's somewhat like memoization, and kind of like caching, but not quite.
The application of this construct is so described: Every so often I want a method to load complex data from Active Directory to load into our database before returning the results from the table. This ensures that we have recent data in our database. However, the time to execute this is high, and 99% of the time nothing has changed. So I want to limit the checking for changes to long timespans in my web app. So, using this construct I can say "only do the long version every X hours, and once it's been done, don't do it again for X more hours."
Implementation
The ICurrentDateTimeProvider
simply has a Now
property so it can be faked for unit tests.
public interface ICurrentDateTimeProvider
{
DateTime Now { get; }
}
public class CurrentDateTimeProvider : ICurrentDateTimeProvider
{
public DateTime Now { get { return DateTime.Now; } }
}
public class ReturnDifferentValueEverySoOften<T>
{
public ReturnDifferentValueEverySoOften(T firstAndSometimes, T most, TimeSpan flipTime = default(TimeSpan), ICurrentDateTimeProvider provider = null)
{
FirstAndSometimes = firstAndSometimes;
MostOfTheTime = most;
if (flipTime == default(TimeSpan))
flipTime = TimeSpan.FromHours(6);
FlipTime = flipTime;
if (provider == null)
provider = new CurrentDateTimeProvider();
DateTimeProvider = provider;
}
public void SetTimeProvider(ICurrentDateTimeProvider provider)
{
DateTimeProvider = provider;
}
public T FirstAndSometimes;
public T MostOfTheTime;
ICurrentDateTimeProvider DateTimeProvider { get; set; }
TimeSpan FlipTime;
DateTime LastFlip { get; set; }
DateTime NextFlip { get { return LastFlip.Add(FlipTime); } }
bool ever = false;
public T Get()
{
var now = DateTimeProvider.Now;
if (!ever)
{
ever = true;
LastFlip = now;
return FirstAndSometimes;
}
if (NextFlip < now)
{
LastFlip = now.Add(FlipTime);
return FirstAndSometimes;
}
return MostOfTheTime;
}
}
Unit Test
Below is a unit test I wrote to ensure that it functions properly:
[Fact]
public void CanFlipBetweenValues()
{
var timeToWait = TimeSpan.FromMilliseconds(10);
var currentTime = DateTime.Now;
var timeProvider = new Mock<ICurrentDateTimeProvider>();
timeProvider.SetupGet(x => x.Now).Returns(currentTime);
var cacher = new ReturnDifferentValueEverySoOften<bool>(false, true, timeToWait);
cacher.SetTimeProvider(timeProvider.Object);
Assert.False(cacher.Get());
Assert.True(cacher.Get());
Assert.True(cacher.Get());
Assert.True(cacher.Get());
Assert.True(cacher.Get());
//add some arbitrary time > timeToWait
var newTime = currentTime.Add(timeToWait).Add(new TimeSpan(0, 0, 1));
var newTimeProvider = new Mock<ICurrentDateTimeProvider>();
newTimeProvider.SetupGet(x => x.Now).Returns(newTime);
cacher.SetTimeProvider(newTimeProvider.Object);
Assert.False(cacher.Get());
Assert.True(cacher.Get());
Assert.True(cacher.Get());
Assert.True(cacher.Get());
Assert.True(cacher.Get());
}
Again, I'm mostly looking to see if there exists a better name for something like this, but I'm open to other code review suggestions as well.
If (delay.HasPassed) { loadFromAD() }
\$\endgroup\$ – TessellatingHeckler Jun 29 '15 at 18:27if(cacher.Get()) loadADData();
thanks for the suggestions \$\endgroup\$ – DLeh Jun 29 '15 at 18:31TimeSensitiveLatch
. thanks for your input. \$\endgroup\$ – DLeh Jun 29 '15 at 18:41