Files
2026-09-29 16:28:20 +00:00

72 lines
2.1 KiB
C#

// Example 2 solution — Weather Station domain 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 SprinklerController(() => 200).
//
// Condensed mechanics: https://sammancoaching.org/refactorings/slice.html
// (where that page says mock, we use a lambda instead).
using System;
public enum SunExposure
{
Shady,
Sunny
}
public enum WateringDuration
{
None,
Medium,
Short
}
public class LightSensor
{
private readonly Random _rng = new Random(); // stand-in for hardware noise
public byte Read()
{
return (byte)_rng.Next(256);
}
}
public class SprinklerController
{
private readonly Func<byte> _readLight; // the sensor, as a lambda
private bool _wateredToday; // event-style client state
public SprinklerController(Func<byte> readLight)
{
_readLight = readLight;
}
public WateringDuration ScheduleWatering()
{
Func<byte> readLight = () => _readLight(); // lambda definition at the top
return ScheduleWateringTail(readLight); // pass the lambda on
}
private WateringDuration ScheduleWateringTail(Func<byte> readLight)
{
if (_wateredToday) // guard: client state, stays
{
return WateringDuration.None;
}
_wateredToday = true; // set only after watering
byte reading = readLight(); // middle: the stubbed lambda
SunExposure exposure = ToSunExposure(reading);
if (exposure == SunExposure.Sunny) // tail: complex behaviour below
{ // the extraction point
return WateringDuration.Medium;
}
return WateringDuration.Short;
}
private static SunExposure ToSunExposure(byte reading)
{
return reading > 128 ? SunExposure.Sunny : SunExposure.Shady;
}
}