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
68 lines
5.0 KiB
XML
68 lines
5.0 KiB
XML
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 460" font-family="Helvetica, Arial, sans-serif">
|
|
<defs>
|
|
<marker id="arrR" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
|
<path d="M0,0 L10,5 L0,10 z" fill="#dc2626"/>
|
|
</marker>
|
|
<marker id="arrP" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
|
<path d="M0,0 L10,5 L0,10 z" fill="#9333ea"/>
|
|
</marker>
|
|
</defs>
|
|
<rect width="760" height="460" fill="#ffffff"/>
|
|
<text x="24" y="34" font-size="20" font-weight="bold" fill="#0f172a">Step 3 — extract the weather loop; the lambda becomes a parameter</text>
|
|
<text x="24" y="56" font-size="13" fill="#475569">Extract Method on the expectedWeather block. Checkpoint: grep scorer → no hits; try static → compiles.</text>
|
|
|
|
<!-- left: original method -->
|
|
<rect x="50" y="74" width="300" height="356" rx="10" fill="#f8fafc" stroke="#64748b" stroke-width="1.5"/>
|
|
<text x="66" y="96" font-size="14" font-weight="bold" fill="#0f172a">longRangeForecast()</text>
|
|
|
|
<!-- lambda at top -->
|
|
<rect x="64" y="104" width="272" height="68" rx="8" fill="#faf5ff" stroke="#9333ea" stroke-width="1.5"/>
|
|
<text x="78" y="126" font-size="12" font-weight="bold" fill="#9333ea">λ dayOffsetToWeather</text>
|
|
<text x="78" y="146" font-size="10" font-family="Menlo, Consolas, monospace" fill="#dc2626">scorer.updateSelection();</text>
|
|
<text x="78" y="162" font-size="10" font-family="Menlo, Consolas, monospace" fill="#dc2626">return scorer.lookupWeather(daysForward);</text>
|
|
|
|
<!-- reset loop -->
|
|
<rect x="64" y="188" width="272" height="44" rx="8" fill="#eef2ff" stroke="#818cf8"/>
|
|
<text x="78" y="214" font-size="11" font-family="Menlo, Consolas, monospace" fill="#1e1b4b">reset loop: result.put(flavour, 0)</text>
|
|
|
|
<!-- call site -->
|
|
<rect x="64" y="248" width="272" height="48" rx="8" fill="#ffffff" stroke="#475569" stroke-width="1.5"/>
|
|
<text x="78" y="268" font-size="11" font-family="Menlo, Consolas, monospace" fill="#0f172a">expectedWeather =</text>
|
|
<text x="78" y="286" font-size="11" font-family="Menlo, Consolas, monospace" fill="#0f172a">collectExpectedWeather(<tspan fill="#9333ea" font-weight="bold">λ</tspan>)</text>
|
|
|
|
<!-- scoring loop -->
|
|
<rect x="64" y="312" width="272" height="84" rx="8" fill="#eef2ff" stroke="#818cf8"/>
|
|
<text x="78" y="334" font-size="11" font-family="Menlo, Consolas, monospace" fill="#1e1b4b">for (flavour : keySet) result += 10</text>
|
|
<text x="78" y="354" font-size="11" font-family="Menlo, Consolas, monospace" fill="#1e1b4b">if (sunny > 2 && Vanilla) += 5</text>
|
|
<text x="78" y="374" font-size="11" font-family="Menlo, Consolas, monospace" fill="#1e1b4b">if (sunny > 1 && weather[1]) += 2</text>
|
|
|
|
<!-- purple arrow: lambda becomes parameter -->
|
|
<line x1="340" y1="272" x2="452" y2="146" stroke="#9333ea" stroke-width="1.5" marker-end="url(#arrP)"/>
|
|
<text x="396" y="214" font-size="10" font-weight="bold" fill="#9333ea" text-anchor="middle" transform="rotate(-48 396 214)">λ becomes a parameter</text>
|
|
|
|
<!-- right: extracted method -->
|
|
<rect x="440" y="74" width="290" height="280" rx="10" fill="#f8fafc" stroke="#64748b" stroke-width="1.5"/>
|
|
<text x="456" y="96" font-size="13" font-weight="bold" fill="#0f172a">collectExpectedWeather</text>
|
|
<text x="456" y="112" font-size="11" fill="#475569">static — no fields, all inputs are parameters</text>
|
|
|
|
<!-- parameter pill -->
|
|
<rect x="456" y="122" width="258" height="32" rx="16" fill="#faf5ff" stroke="#9333ea" stroke-width="1.5"/>
|
|
<text x="585" y="142" font-size="11" font-weight="bold" fill="#9333ea" text-anchor="middle">λ LongFunction<Boolean> dayOffsetToWeather</text>
|
|
|
|
<!-- weather loop -->
|
|
<rect x="456" y="166" width="258" height="110" rx="8" fill="#eef2ff" stroke="#818cf8"/>
|
|
<text x="470" y="190" font-size="11" font-family="Menlo, Consolas, monospace" fill="#1e1b4b">for (Instant d : DATES)</text>
|
|
<text x="470" y="212" font-size="11" font-family="Menlo, Consolas, monospace" fill="#1e1b4b">daysForward = between(ANCHOR, d)</text>
|
|
<text x="470" y="234" font-size="11" font-family="Menlo, Consolas, monospace" fill="#1e1b4b">expected.add(<tspan fill="#9333ea" font-weight="bold">λ</tspan>.apply(daysForward))</text>
|
|
<text x="470" y="260" font-size="10" fill="#64748b">no scorer reference in here</text>
|
|
|
|
<text x="456" y="308" font-size="11" font-family="Menlo, Consolas, monospace" fill="#0f172a">return expectedWeather;</text>
|
|
|
|
<!-- scorer, out of reach -->
|
|
<rect x="560" y="386" width="160" height="50" rx="8" fill="#fef2f2" stroke="#dc2626" stroke-width="1.5" stroke-dasharray="4 3"/>
|
|
<text x="640" y="408" font-size="12" font-weight="bold" fill="#dc2626" text-anchor="middle">Scorer</text>
|
|
<text x="640" y="426" font-size="10" fill="#7f1d1d" text-anchor="middle">out of reach from in here</text>
|
|
<line x1="640" y1="384" x2="640" y2="360" stroke="#dc2626" stroke-width="1.5" stroke-dasharray="5 4" marker-end="url(#arrR)"/>
|
|
<text x="650" y="376" font-size="10" font-weight="bold" fill="#dc2626">✗ cannot reach in</text>
|
|
</svg>
|