Interface vs implementation

인터페이스와 구현

Callers depend on a behavior contract while different implementations provide it.

···
html
<div class="visual contract" data-step="0"><div class="visual-head"><strong>ONE CONTRACT</strong><i></i></div><div class="visual-scene"><div class="contract-call">save()</div><div class="contract-wire">→</div><div class="contract-port">Storage<br><small>interface</small></div><div class="contract-wire">→</div><div class="contract-impl"><span>memory</span><span>file</span></div></div><div class="visual-caption"></div><div class="visual-dots"><b></b><b></b><b></b><b></b></div></div>
css
.visual{width:min(95vw,760px);height:min(91vh,330px);padding:clamp(9px,2.5vmin,18px);display:flex;flex-direction:column;gap:clamp(6px,1.7vmin,11px);border:1px solid var(--line);border-radius:13px;background:var(--surface);font:500 clamp(12px,3.4vmin,16px)/1.25 var(--font-sans,-apple-system),sans-serif}
.visual-head{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:19px;color:var(--accent)}.visual-head strong{font-size:1em}.visual-head i{display:block;width:8px;height:8px;flex:none;border-radius:50%;background:var(--accent);animation:visual-pulse 1.3s infinite}@keyframes visual-pulse{50%{opacity:.25}}
.visual-scene{position:relative;flex:1;min-height:0;overflow:hidden}.visual-caption{min-height:2.4em;display:grid;place-items:center;text-align:center}.visual-dots{display:flex;justify-content:center;gap:4px}.visual-dots b{display:block;width:15px;height:3px;border-radius:3px;background:var(--line)}.visual-dots b.on{background:var(--accent)}
.visual-scene *{box-sizing:border-box}.visual-scene .mono{font-family:ui-monospace,monospace}.visual-scene .muted{color:var(--muted)}.visual-scene .lit{border-color:var(--accent)!important;background:color-mix(in srgb,var(--accent) 14%,var(--surface))!important;color:var(--fg)!important}
.contract .visual-scene{display:flex;align-items:center;justify-content:center;gap:3px}.contract-call,.contract-port{border:1px solid var(--line);border-radius:7px;padding:9px 5px;background:var(--bg);text-align:center}.contract-call{font:600 12px ui-monospace,monospace}.contract-port{border-color:var(--accent)}.contract-port small{font-size:12px;color:var(--muted)}.contract-wire{color:var(--accent);font-size:18px}.contract-impl{display:flex;flex-direction:column;gap:5px}.contract-impl span{border:1px solid var(--line);border-radius:5px;background:var(--bg);padding:5px;transition:background .3s}.contract[data-step="0"] .contract-call,.contract[data-step="1"] .contract-port,.contract[data-step="2"] .contract-impl span:first-child,.contract[data-step="3"] .contract-impl span:last-child{background:color-mix(in srgb,var(--accent) 15%,var(--surface));border-color:var(--accent)}
js
const root=document.querySelector('.visual'),cap=root.querySelector('.visual-caption'),dots=[...root.querySelectorAll('.visual-dots b')],captions=["Caller invokes save()","Interface names the behavior","Memory implementation","File implementation"];let step=0;function advance(){root.dataset.step=String(step);cap.textContent=captions[step];dots.forEach((d,i)=>d.classList.toggle('on',i===step));if(root.classList.contains('generic')){root.querySelector('.generic-input').textContent=step===3?'"hi"':'7';root.querySelector('.generic-output').textContent=step===3?'"hi" : string':'7 : number'}if(root.classList.contains('union'))root.querySelector('.set-value').textContent=step%2?'value: "seven"':'value: 7';step=(step+1)%captions.length}advance();let timer=setInterval(advance,1100);root.addEventListener('pointerdown',()=>{clearInterval(timer);advance()})

An interface states a method contract while an implementation supplies behavior. Any object satisfying the interface can replace another without changing the caller.

The demo routes Storage.save to memory and file implementations in turn. Keep contracts focused so implementations do not carry unrelated methods.

When to use

Use it to swap storage or transport dependencies, including test implementations.

Open as page ↗