Decorator Pattern in Dart: Widgets Already Use It
You've been using the decorator pattern in Dart every day without knowing it — Padding and Center are decorators. Learn the GoF pattern properly, then stack logging and caching decorators in pure Dart.
You have a Text widget. Now it needs padding. Then centering. Then a tap handler and a tooltip. If you reached for subclassing — PaddedCenteredTappableText extends Text — congratulations: you've rebuilt the exact problem this decorator pattern Dart guide exists to eliminate. Every new combination of behaviors multiplies your subclasses until the hierarchy collapses. Flutter saw this coming and made a radical choice: almost never subclass widgets; wrap them instead. Padding , Center , GestureDetector aren't widgets in the "thing on screen" sense — they're decorators: transparent layers adding one behavior to whatever child sits inside. This guide starts at your widget tree, then builds the classic pattern in pure Dart 3.13, stacks logging and caching decorators, and shows exactly when decorating beats inheritance. What you'll learn Why Flutter's widget tree is a decorator chain (and why that beats subclassing) The four parts of the classic decorator: component, concrete component, decorator, concrete decorators A runnable coffee-shop example in modern Dart 3.13 How to stack logging + caching decorators, and why order matters A decision table: decorator vs subclassing vs extension methods The four mistakes that make decorator stacks unmaintainable All code targets Dart 3.13 (ships with Flutter 3.47 ) and runs with plain dart run . Your widget tree is already a decorator chain Look at the most ordinary Flutter code imaginable: Padding( padding: const EdgeInsets.all(8.0), child: Center( child: Text('Hello'), ), ) Text doesn't know about padding. Padding doesn't know it's wrapping text — it wraps *any* widget. Each layer adds exactly one behavior (spacing, alignment) without touching the thing inside. That is the decorator…