Skip to content

Patterns in Real Frameworks

Design patterns aren’t just theory — they’re everywhere in frameworks you already use.


PatternWhere in React
ObserverReact’s reactivity — state changes trigger re-renders. useEffect subscribes to changes.
DecoratorHigher-Order Components (HOC) like connect(), withRouter(), withAuth() wrap a component to add behavior
Factory MethodReact.createElement() creates virtual DOM nodes
CompositeReact components form a tree — parent components contain child components
ProxyReact.memo() — proxies the component to add memoization
CommandRedux actions — each action is a command object dispatched to reducers
StrategyRender props — swap rendering logic by passing different render functions
StateuseReducer — state transitions are explicit
IteratorReact Router Route matching — iterates through routes to find a match
BuilderJSX — builds virtual DOM tree step by step (Babel compiles it to React.createElement calls)
Chain of ResponsibilityExpress/Next.js middleware — each middleware processes or passes to next()
Template MethodReact lifecycle methods — the framework calls componentDidMount, render, etc.
// Decorator (HOC)
const withAuth = (Component) => {
return (props) => {
const user = useAuth();
return user ? <Component {...props} /> : <Login />;
};
};
const ProtectedDashboard = withAuth(Dashboard);
// Observer (using hooks)
useEffect(() => {
// Subscribe to data changes
const unsub = store.subscribe(() => { /* update */ });
return unsub; // Cleanup on unmount
}, []);

PatternWhere in Angular
Dependency InjectionCore to Angular — services are injected via constructor
SingletonServices registered at root level are singletons
ObserverRxJS Observables — HTTP, forms, route params, event emitters
Decorator@Component, @Injectable, @Directive — TypeScript decorators
FacadeAngular Forms — complex validation logic behind simple directives
ProxyHttpInterceptor — intercepts and transforms HTTP requests
CommandRouter events — navigation commands queued and processed
BuilderFormBuilder — builds reactive forms step by step
@Injectable({ providedIn: 'root' })
class LoggerService {
log(msg: string) { console.log(msg); }
}
@Component({ /* ... */ })
class UserComponent {
constructor(private logger: LoggerService) { // ✅ DI
this.logger.log('Component loaded');
}
}

PatternWhere in Node.js
ObserverEventEmitter — emitter.on('event', handler)
Chain of ResponsibilityExpress middleware — app.use(middleware1)
Facadefs/promises — wraps complex POSIX file operations
StrategyPassport.js — swap authentication strategies (passport.use(new LocalStrategy(...)))
SingletonModule cache — require() returns the same instance
ProxyProxies in frameworks — fastify, express-http-proxy
CommandBull / job queues — each job is a command
BuilderKnex.js — query builder: knex('users').where('id', 1).first()
const EventEmitter = require('events');
class OrderService extends EventEmitter {
createOrder(order) {
// ... save order
this.emit('order:created', order);
}
}
const orders = new OrderService();
orders.on('order:created', (order) => {
emailService.sendConfirmation(order);
});
orders.on('order:created', (order) => {
inventoryService.updateStock(order);
});

PatternWhere in Spring
SingletonSpring beans are singletons by default
Dependency Injection@Autowired — core to Spring
ProxyAOP — @Transactional creates a proxy
Template MethodJdbcTemplate — defines DB access skeleton
Factory MethodBeanFactory / ApplicationContext
DecoratorSpring Security filters — chain of decorators

PatternReactAngularNode.js
ObserveruseEffect, hooksRxJSEventEmitter
DecoratorHOC@Component—
Dependency Injection—@Injectable—
Chain of Resp.MiddlewareHttpInterceptorExpress middleware
SingletonModuleRoot serviceModule cache
BuilderJSXFormBuilderKnex.js

  • You already use design patterns — you just didn’t know their names
  • Frameworks are built WITH patterns; you use them THROUGH frameworks
  • Understanding patterns helps you understand why frameworks work the way they do
  • Recognizing patterns in familiar frameworks makes learning new ones easier