- MetaphorFree.cs: guard -> SomeDependency.mightThrowWhenPreconditionNotSatisfied(a) -> tail, capture-to-parameter story for the deck - WeatherStation.cs: SprinklerController, LightSensor.Read() byte -> SunExposure, tail branches - IceCreamShop.cs: third repetition, Thermometer byte -> Warmth, tail branches
80 lines
2.4 KiB
C#
80 lines
2.4 KiB
C#
// Example 3 — Ice cream shop demo of Slice with Lambda (C#)
|
|
//
|
|
// Condensed mechanics: https://sammancoaching.org/refactorings/slice.html
|
|
// (where that page says mock, we use a lambda instead).
|
|
//
|
|
// Third repetition, same complexity as ScheduleWatering in WeatherStation.cs
|
|
// (guard -> one dependency call -> map to enum -> constant tail), so
|
|
// participants can practice extracting a lambda a second time. The C#
|
|
// delegate syntax is worth the repetition:
|
|
//
|
|
// Func<byte> readTemperature = () => _thermometer.Read();
|
|
//
|
|
// Cast:
|
|
// Thermometer — hardware-ish dependency. Read() returns a raw
|
|
// byte value (not calibrated, the client decides
|
|
// what it means).
|
|
// Warmth — enum. Reading > 25 => Warm, otherwise Cold.
|
|
// (Sunny/Shady's cousin from WeatherStation.cs.)
|
|
// ThawAmount — enum. None / Medium / Low.
|
|
// IceCreamShop — the client. Owns the _thawedToday flag, so the
|
|
// guard is about client state, not sensor state.
|
|
|
|
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 Thermometer _thermometer;
|
|
private bool _thawedToday; // event-style client state
|
|
|
|
public IceCreamShop(Thermometer thermometer)
|
|
{
|
|
_thermometer = thermometer;
|
|
}
|
|
|
|
public ThawAmount ThawStock()
|
|
{
|
|
if (_thawedToday) // guard: client state, stays
|
|
{
|
|
return ThawAmount.None;
|
|
}
|
|
|
|
_thawedToday = true; // set only after thawing
|
|
byte temperature = _thermometer.Read(); // middle: unwanted dependency
|
|
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;
|
|
}
|
|
}
|