Skip to main content

behavioral

Behavioral design patterns from the Gang of Four — Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, and Visitor. Patterns that manage algorithms, relationships, and responsibilities between objects. USE FOR: object communication, event handling, state management, algorithm encapsulation, request handling chains, undo/redo, publish-subscribe DO NOT USE FOR: object creation (use creational), structural composition (use structural)

Datos de origen

Repositorio
Tyler-R-Kendrick/agent-skills
Última actividad en el origen
11 de febrero de 2026 a las 05:14
Idioma detectado de SKILL.md
inglés
Estrellas
12
Forks
4

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Explorador de archivos
4 archivos

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
behavioral
description
Behavioral design patterns from the Gang of Four — Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, and Visitor. Patterns that manage algorithms, relationships, and responsibilities between objects. USE FOR: object communication, event handling, state management, algorithm encapsulation, request handling chains, undo/redo, publish-subscribe DO NOT USE FOR: object creation (use creational), structural composition (use structural)
license
MIT
metadata
{"displayName":"Behavioral Patterns","author":"Tyler-R-Kendrick"}
compatibility
claude, copilot, cursor
references
[{"title":"Refactoring.Guru — Behavioral Design Patterns","url":"https://refactoring.guru/design-patterns/behavioral-patterns"},{"title":"Behavioral Pattern — Wikipedia","url":"https://en.wikipedia.org/wiki/Behavioral_pattern"}]
# Behavioral Design Patterns ## Overview Behavioral patterns are concerned with algorithms and the assignment of responsibilities between objects. They describe not just patterns of objects or classes but also the patterns of communication between them. These patterns characterize complex control flow that is difficult to follow at run-time — they shift your focus away from flow of control to the way objects are interconnected. --- ## 1. Chain of Responsibility ### Intent Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it. ### Structure ``` ┌──────────────────┐ │ Handler │◀────────────┐ │ (interface) │ │ next ├──────────────────┤ │ │ + handle(req) │─────────────┘ │ + setNext(h) │ └──────┬───────────┘ │ implements ├──────────────┬──────────────┐ ▼ ▼ ▼ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ HandlerA │ │ HandlerB │ │ HandlerC │ └────────────┘ └────────────┘ └────────────┘ ``` ### Participants - **Handler** — defines an interface for handling requests; optionally links to a successor - **ConcreteHandler** — handles requests it is responsible for; forwards unhandled requests to the next handler - **Client** — initiates the request to a handler in the chain ### When to Use - More than one object may handle a request, and the handler is not known a priori - You want to issue a request to one of several objects without specifying the receiver explicitly - The set of handlers should be configurable dynamically (e.g., middleware pipelines) ### TypeScript Example ```typescript // Handler interface interface SupportHandler { setNext(handler: SupportHandler): SupportHandler; handle(issue: { level: string; message: string }): string; } // Base handler abstract class BaseSupportHandler implements SupportHandler { private next: SupportHandler | null = null; setNext(handler: SupportHandler): SupportHandler { this.next = handler; return handler; } handle(issue: { level: string; message: string }): string { if (this.next) { return this.next.handle(issue); } return `No handler found for: ${issue.message}`; } } // Concrete handlers class TierOneSupport extends BaseSupportHandler { handle(issue: { level: string; message: string }): string { if (issue.level === "basic") { return `[Tier 1] Resolved: ${issue.message}`; } return super.handle(issue); } } class TierTwoSupport extends BaseSupportHandler { handle(issue: { level: string; message: string }): string { if (issue.level === "intermediate") { return `[Tier 2] Resolved: ${issue.message}`; } return super.handle(issue); } } class EngineeringSupport extends BaseSupportHandler { handle(issue: { level: string; message: string }): string { if (issue.level === "critical") { return `[Engineering] Resolved: ${issue.message}`; } return super.handle(issue); } } // Usage — build the chain const tier1 = new TierOneSupport(); const tier2 = new TierTwoSupport(); const engineering = new EngineeringSupport(); tier1.setNext(tier2).setNext(engineering); console.log(tier1.handle({ level: "basic", message: "Password reset" })); // [Tier 1] Resolved: Password reset console.log(tier1.handle({ level: "critical", message: "Data corruption" })); // [Engineering] Resolved: Data corruption ``` --- ## 2. Command ### Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations. ### Structure ``` ┌──────────┐ ┌──────────────────┐ ┌──────────────┐ │ Invoker │──────▶│ Command │ │ Receiver │ │ │ │ (interface) │ ├──────────────┤ └──────────┘ ├──────────────────┤ │ + action() │ │ + execute() │ └──────┬───────┘ │ + undo() │ │ └──────┬───────────┘ │ │ implements │ ▼ │ ┌──────────────────┐ │ │ ConcreteCommand │──────────────┘ ├──────────────────┤ calls │ - receiver │ │ - state │ │ + execute() │ │ + undo() │ └──────────────────┘ ``` ### Participants - **Command** — declares an interface for executing an operation - **ConcreteCommand** — binds a Receiver to an action; implements execute/undo - **Invoker** — asks the command to carry out the request - **Receiver** — knows how to perform the operations associated with the request ### When to Use - You need to parameterize objects with an action to perform - You need to specify, queue, and execute requests at different times - You need to support undo/redo - You need to support logging changes so they can be reapplied after a crash ### TypeScript Example ```typescript // Receiver class TextEditor { content = ""; insert(text: string, position: number): void { this.content = this.content.slice(0, position) + text + this.content.slice(position); } delete(position: number, length: number): string { const deleted = this.content.slice(position, position + length); this.content = this.content.slice(0, position) + this.content.slice(position + length); return deleted; } } // Command interface interface EditorCommand { execute(): void; undo(): void; } // Concrete commands class InsertCommand implements EditorCommand { constructor( private editor: TextEditor, private text: string, private position: number ) {} execute(): void { this.editor.insert(this.text, this.position); } undo(): void { this.editor.delete(this.position, this.text.length); } } class DeleteCommand implements EditorCommand { private deletedText = ""; constructor( private editor: TextEditor, private position: number, private length: number ) {} execute(): void { this.deletedText = this.editor.delete(this.position, this.length); } undo(): void { this.editor.insert(this.deletedText, this.position); } } // Invoker with undo/redo class CommandHistory { private undoStack: EditorCommand[] = []; private redoStack: EditorCommand[] = []; execute(command: EditorCommand): void { command.execute(); this.undoStack.push(command); this.redoStack = []; // clear redo on new action } undo(): void { const cmd = this.undoStack.pop(); if (cmd) { cmd.undo(); this.redoStack.push(cmd); } } redo(): void { const cmd = this.redoStack.pop(); if (cmd) { cmd.execute(); this.undoStack.push(cmd); } } } // Usage const editor = new TextEditor(); const history = new CommandHistory(); history.execute(new InsertCommand(editor, "Hello", 0)); history.execute(new InsertCommand(editor, " World", 5)); console.log(editor.content); // "Hello World" history.undo(); console.log(editor.content); // "Hello" history.redo(); console.log(editor.content); // "Hello World" ``` --- ## 3. Iterator ### Intent Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation. ### Structure ``` ┌──────────────────┐ ┌──────────────────┐ │ Aggregate │───────▶│ Iterator │ │ (interface) │creates │ (interface) │ ├──────────────────┤ ├──────────────────┤ │ + createIterator()│ │ + hasNext(): bool │ └──────────────────┘ │ + next(): T │ └──────────────────┘ ``` ### Participants - **Iterator** — defines an interface for accessing and traversing elements - **ConcreteIterator** — implements the Iterator interface; tracks the current position - **Aggregate** — defines an interface for creating an Iterator object - **ConcreteAggregate** — returns an instance of the ConcreteIterator ### When to Use - You want to access a collection's elements without exposing its internal structure - You want to support multiple traversals of the same collection - You want a uniform interface for traversing different types of collections ### TypeScript Example ```typescript // Iterator interface interface Iterator<T> { hasNext(): boolean; next(): T; reset(): void; } // Concrete collection with custom iterator class TreeNode<T> { children: TreeNode<T>[] = []; constructor(public value: T) {} add(...nodes: TreeNode<T>[]): this { this.children.push(...nodes); return this; } } // Depth-first iterator class DepthFirstIterator<T> implements Iterator<T> { private stack: TreeNode<T>[]; constructor(private root: TreeNode<T>) { this.stack = [root]; } hasNext(): boolean { return this.stack.length > 0; } next(): T { if (!this.hasNext()) throw new Error("No more elements"); const node = this.stack.pop()!; // Push children in reverse so left child is processed first for (let i = node.children.length - 1; i >= 0; i--) { this.stack.push(node.children[i]); } return node.value; } reset(): void { this.stack = [this.root]; } } // Breadth-first iterator class BreadthFirstIterator<T> implements Iterator<T> { private queue: TreeNode<T>[]; constructor(private root: TreeNode<T>) { this.queue = [root]; } hasNext(): boolean { return this.queue.length > 0; } next(): T { if (!this.hasNext()) throw new Error("No more elements"); const node = this.queue.shift()!; this.queue.push(...node.children); return node.value; } reset(): void { this.queue = [this.root]; } } // Usage const tree = new TreeNode("A") .add( new TreeNode("B").add(new TreeNode("D"), new TreeNode("E")), new TreeNode("C").add(new TreeNode("F")) ); const dfs = new DepthFirstIterator(tree); const dfsResult: string[] = []; while (dfs.hasNext()) dfsResult.push(dfs.next()); console.log("DFS:", dfsResult.join(" -> ")); // A -> B -> D -> E -> C -> F const bfs = new BreadthFirstIterator(tree); const bfsResult: string[] = []; while (bfs.hasNext()) bfsResult.push(bfs.next()); console.log("BFS:", bfsResult.join(" -> ")); // A -> B -> C -> D -> E -> F ``` --- ## 4. Mediator ### Intent Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently. ### Structure ``` ┌──────────────────┐ ┌──────────────────┐ │ Mediator │◀───────│ Colleague │ │ (interface) │ │ (interface) │ ├──────────────────┤ ├──────────────────┤ │ + notify(sender, │ │ - mediator │ │ event) │ └──────┬───────────┘ └──────┬───────────┘ │ implements │ implements ├──────────┐ ▼ ▼ ▼ ┌──────────────────┐ ┌──────────┐┌──────────┐ │ ConcreteMediator │ │ColleagueA││ColleagueB│ │ │ └──────────┘└──────────┘ │ - colleagueA │ │ - colleagueB │ └──────────────────┘ ``` ### Participants - **Mediator** — defines an interface for communicating with Colleague objects - **ConcreteMediator** — implements cooperative behavior by coordinating Colleague objects - **Colleague** — each Colleague knows its Mediator and communicates with it instead of other Colleagues ### When to Use - A set of objects communicate in well-defined but complex ways - Reusing an object is difficult because it refers to and communicates with many other objects - A behavior distributed between several classes should be customizable without subclassing ### TypeScript Example ```typescript // Mediator interface interface ChatMediator { sendMessage(message: string, sender: ChatUser): void; addUser(user: ChatUser): void; } // Colleague class ChatUser { private messages: string[] = []; constructor( public name: string, private mediator: ChatMediator ) { mediator.addUser(this); } send(message: string): void { console.log(`${this.name} sends: ${message}`); this.mediator.sendMessage(message, this); } receive(message: string, from: string): void { const formatted = `${from}: ${message}`; this.messages.push(formatted); console.log(` ${this.name} received <- ${formatted}`); } getHistory(): string[] { return [...this.messages]; } } // Concrete mediator class ChatRoom implements ChatMediator { private users: ChatUser[] = []; addUser(user: ChatUser): void { this.users.push(user); } sendMessage(message: string, sender: ChatUser): void { for (const user of this.users) { if (user !== sender) { user.receive(message, sender.name); } } } } // Usage — users never reference each other directly const room = new ChatRoom(); const alice = new ChatUser("Alice", room); const bob = new ChatUser("Bob", room); const charlie = new ChatUser("Charlie", room); alice.send("Hello everyone!"); // Alice sends: Hello everyone! // Bob received <- Alice: Hello everyone! // Charlie received <- Alice: Hello everyone! bob.send("Hey Alice!"); // Bob sends: Hey Alice! // Alice received <- Bob: Hey Alice! // Charlie received <- Bob: Hey Alice! ``` --- ## 5. Memento ### Intent Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later. ### Structure ``` ┌──────────────┐ ┌──────────────────┐ ┌──────────────┐ │ Caretaker │────▶│ Memento │◀────│ Originator │ ├──────────────┤keeps│ (opaque) │saves├──────────────┤ │ - mementos[] │ ├──────────────────┤ │ - state │ └──────────────┘ │ + getState() │ │ + save() │ └──────────────────┘ │ + restore(m) │ └──────────────┘ ```
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub