72 lines
2.0 KiB
C#
72 lines
2.0 KiB
C#
// Example 3 solution — Ice cream shop demo of Slice with Lambda (C#), after
|
|
//
|
|
// Lambda extracted (step 1), slid to the top (step 2), method extracted
|
|
// below the guard (step 3). The constructor now takes the lambda directly,
|
|
// so tests construct with new IceCreamShop(() => 30).
|
|
//
|
|
// Condensed mechanics: https://sammancoaching.org/refactorings/slice.html
|
|
// (where that page says mock, we use a lambda instead).
|
|
|
|
using System;
|
|
|
|
public enum Warmth
|
|
{
|
|
Cold,
|
|
Warm
|
|
}
|
|
|
|
public enum ThawAmount
|
|
{
|
|
None,
|
|
Medium,
|
|
Low
|
|
}
|
|
|
|
public class Thermometer
|
|
{
|
|
private readonly Random _rng = new Random(); // stand-in for the hardware
|
|
|
|
public byte Read()
|
|
{
|
|
return (byte)_rng.Next(50); // raw sensor value
|
|
}
|
|
}
|
|
|
|
public class IceCreamShop
|
|
{
|
|
private readonly Func<byte> _readTemperature; // the thermometer, as a lambda
|
|
private bool _thawedToday; // event-style client state
|
|
|
|
public IceCreamShop(Func<byte> readTemperature)
|
|
{
|
|
_readTemperature = readTemperature;
|
|
}
|
|
|
|
public ThawAmount ThawStock()
|
|
{
|
|
Func<byte> readTemperature = () => _readTemperature(); // lambda at the top
|
|
return ThawStockTail(readTemperature); // pass the lambda on
|
|
}
|
|
|
|
private ThawAmount ThawStockTail(Func<byte> readTemperature)
|
|
{
|
|
if (_thawedToday) // guard: client state, stays
|
|
{
|
|
return ThawAmount.None;
|
|
}
|
|
|
|
_thawedToday = true; // set only after thawing
|
|
byte temperature = readTemperature(); // middle: the stubbed lambda
|
|
Warmth warmth = ToWarmth(temperature);
|
|
if (warmth == Warmth.Warm) // tail: complex behaviour below
|
|
{ // the extraction point
|
|
return ThawAmount.Medium;
|
|
}
|
|
return ThawAmount.Low;
|
|
}
|
|
|
|
private static Warmth ToWarmth(byte temperature)
|
|
{
|
|
return temperature > 25 ? Warmth.Warm : Warmth.Cold;
|
|
}
|
|
} |