The refactoring is now published as Slice on sammancoaching.org: https://sammancoaching.org/refactorings/slice.html - git mv ideas/split-loop-with-lambda -> ideas/slice-with-lambda - rename learning-hour file and update frontmatter name - update paths in tools/rehearse scripts and report title - update prose: 'Split Loop with Lambda' -> 'Slice with Lambda' in learning hour, exercise READMEs, storyboard, solution comments - link the published Slice refactoring from the pattern draft
72 lines
2.1 KiB
C#
72 lines
2.1 KiB
C#
// Example 2 — Weather Station domain demo of Slice with Lambda (C#)
|
|
//
|
|
// Condensed mechanics: https://sammancoaching.org/refactorings/slice.html
|
|
// (where that page says mock, we use a lambda instead).
|
|
//
|
|
// Cast (Head First Design Patterns Weather Station, reduced):
|
|
// LightSensor — hardware-ish dependency. Read() returns a byte.
|
|
// SunExposure — enum. Reading > 128 => Sunny, otherwise Shady.
|
|
// WateringDuration — enum. None / Medium / Short.
|
|
// (Long is YAGNI until the for-loop version of this
|
|
// exercise exists.)
|
|
// SprinklerController — the client. Owns the _wateredToday flag, so the
|
|
// guard is about client state, not sensor state.
|
|
|
|
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 LightSensor _lightSensor;
|
|
private bool _wateredToday; // event-style client state
|
|
|
|
public SprinklerController(LightSensor lightSensor)
|
|
{
|
|
_lightSensor = lightSensor;
|
|
}
|
|
|
|
public WateringDuration ScheduleWatering()
|
|
{
|
|
if (_wateredToday) // guard: client state, stays
|
|
{
|
|
return WateringDuration.None;
|
|
}
|
|
|
|
_wateredToday = true; // set only after watering
|
|
byte reading = _lightSensor.Read(); // middle: unwanted dependency
|
|
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;
|
|
}
|
|
}
|