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
55 lines
1.8 KiB
C#
55 lines
1.8 KiB
C#
// Example 1 — Metaphor-free demo of Slice with Lambda (C#)
|
|
//
|
|
// Condensed mechanics: https://sammancoaching.org/refactorings/slice.html
|
|
// (where that page says mock, we use a lambda instead).
|
|
//
|
|
// Shape of the method (per zeroth-draft-of-refactoring-pattern.md):
|
|
//
|
|
// guard clauses — must run first
|
|
// middle: dependency — one call on an object we don't want in the
|
|
// extracted method
|
|
// tail: depends on b — uses the value the dependency produced
|
|
//
|
|
// Deliberately NOT a loop: this is the smallest method that shows the
|
|
// mechanics. The dependency both validates its precondition (using the
|
|
// parameter a) and produces b — one expression, one thing to move into
|
|
// the lambda.
|
|
//
|
|
// Unwanted dependency: SomeDependency — might throw when its precondition
|
|
// on a is not satisfied, and returns an unpredictable value. An approval
|
|
// test on Calculate is flaky until the lambda is stubbed.
|
|
|
|
using System;
|
|
|
|
public class Calculator
|
|
{
|
|
private readonly SomeDependency _someDependency;
|
|
|
|
public Calculator(SomeDependency someDependency)
|
|
{
|
|
_someDependency = someDependency;
|
|
}
|
|
|
|
public int Calculate(int a)
|
|
{
|
|
if (a < 0) return 0; // guard clause: stays
|
|
int b = _someDependency.mightThrowWhenPreconditionNotSatisfied(a); // middle: unwanted dependency
|
|
int c = a + b; // tail: depends on b
|
|
return c * 2;
|
|
}
|
|
}
|
|
|
|
public class SomeDependency
|
|
{
|
|
private readonly Random _rng = new Random(); // stand-in for unpredictable computation
|
|
|
|
public int mightThrowWhenPreconditionNotSatisfied(int a)
|
|
{
|
|
if (a > 99)
|
|
{
|
|
throw new InvalidOperationException("precondition not satisfied");
|
|
}
|
|
return _rng.Next(100);
|
|
}
|
|
}
|