DECORATOR / PRACTICE
One line of text.
Layers of possibility.
You met Decorator through notification senders. Now compose optional extras around a text preview.
YOUR BRIEF
Add extras without teaching the client about each one.
A preview starts with hello. Some callers want a “Note: ” label, some want uppercase, and some want both. Keep the client calling render() while setup chooses the wrappers and their order.
Uppercase outside the label produces NOTE: HELLO. Put the label outside instead and it produces Note: HELLO. Test both, then add a border as another wrapper.
The working starting point
function showPreview(view: TextView): string {
return view.render();
}
const preview = showPreview(new PlainText("hello"));PlainText owns the original string. Each decorator holds a TextView and adds behavior to its returned string. This is object composition, not @decorator syntax.
01 / ASSEMBLE
Give each extra its own wrapper.
Both wrappers use your selected structure. LabelText adds “Note: ”; UppercaseText uppercases the returned text.
Your assembled code
TypeScript preview. Highlighting follows the selected execution.
Shared component interface
interface TextView { render(): string }Concrete component · original text
class PlainText implements TextView {
constructor(private text: string) {}
render(): string { return this.text; }
}LabelText
// Choose all three pieces to assemble this wrapper.UppercaseText
// Choose all three pieces to assemble this wrapper.Client · unaware of the chosen extras
function showPreview(view: TextView): string { return view.render(); }Setup · choose the wrapper order
// Complete a compatible assembly before passing it to the client.02 / RUN & OBSERVE
Same wrappers. Different order.
LabelText(PlainText) should add Note: to hello.
Expected preview: Note: hello
Calls go down ↓ · Results come back up ↑
Choose your pieces, then follow one call through the composed objects.
Output and delegation feedback will appear here.
- ○ Add a label — run to verify
- ○ Uppercase outside the label — run to verify
- ○ Label outside uppercase — run to verify
Each test creates a fresh local chain. Every wrapper must call its supplied inner object once in this exercise. The trace records actual calls and return values; matching text alone does not prove correct delegation.
03 / TRANSFER THE IDEA
One more extra: a border.
Add BorderText outside the uppercase-and-label chain. It should turn NOTE: HELLO into [NOTE: HELLO]. Which edits are needed?
First pass the label case and both wrapper-order cases with the same assembly.
Compare with a complete solution
No timer and no attempt limit. Try another assembly, use a hint, or reveal the answer when it helps.