π§© Facade Γ Iterator
β Combined Intentβ
- Use the
Facade
pattern to provide a simple entry point to a multi-step operation - Use the
Iterator
pattern to sequentially execute a list of tasks inside the facade
This design consolidates complex operations (like logging, user notification, validation, etc.) behind a single faΓ§ade method, while internally iterating over a collection of modular tasks.
β When to Useβ
- You want to simplify the interface for a multi-step workflow
- You want to modularize each step (logging, validation, notification) and reuse or reorder them easily
- You need to maintain a consistent structure for running operations in sequence
β UML Class Diagramβ
β Code Exampleβ
- TypeScript
- PHP
- Python
interface Task {
execute(): void;
}
class LogTask implements Task {
constructor(private message: string) {}
execute(): void {
console.log(`[Log]: ${this.message}`);
}
}
class EmailTask implements Task {
constructor(private recipient: string, private content: string) {}
execute(): void {
console.log(`[Email]: To ${this.recipient} - ${this.content}`);
}
}
class TaskExecutor {
constructor(private tasks: Task[]) {}
runAll(): void {
for (const task of this.tasks) {
task.execute();
}
}
}
class UserRegistrationFacade {
registerUser(user: string): void {
const tasks: Task[] = [
new LogTask(`Registering user: ${user}`),
new EmailTask(user, "Welcome to our service!"),
new LogTask(`User registered successfully: ${user}`),
];
const executor = new TaskExecutor(tasks);
executor.runAll();
}
}
// δ½Ώη¨δΎ
const facade = new UserRegistrationFacade();
facade.registerUser("taro@example.com");
<?php
interface Task {
public function execute(array &$context): void;
}
class LogTask implements Task {
public function execute(array &$context): void {
echo "[LOG] Registering user: " . $context['user'] . PHP_EOL;
}
}
class NotifyTask implements Task {
public function execute(array &$context): void {
echo "[NOTIFY] Welcome message sent to: " . $context['user'] . PHP_EOL;
}
}
class TaskExecutor {
/** @var Task[] */
private array $tasks = [];
public function addTask(Task $task): void {
$this->tasks[] = $task;
}
public function executeAll(array &$context): void {
foreach ($this->tasks as $task) {
$task->execute($context);
}
}
}
class UserRegistrationFacade {
private TaskExecutor $executor;
public function __construct() {
$this->executor = new TaskExecutor();
$this->executor->addTask(new LogTask());
$this->executor->addTask(new NotifyTask());
}
public function registerUser(string $user): void {
$context = ['user' => $user];
$this->executor->executeAll($context);
}
}
// δ½Ώη¨δΎ
$facade = new UserRegistrationFacade();
$facade->registerUser("taro@example.com");
from abc import ABC, abstractmethod
class Task(ABC):
@abstractmethod
def execute(self, context: dict) -> None:
pass
class LogTask(Task):
def execute(self, context: dict) -> None:
print(f"[LOG] Registering user: {context['user']}")
class NotifyTask(Task):
def execute(self, context: dict) -> None:
print(f"[NOTIFY] Welcome message sent to: {context['user']}")
class TaskExecutor:
def __init__(self):
self.tasks: list[Task] = []
def add_task(self, task: Task) -> None:
self.tasks.append(task)
def execute_all(self, context: dict) -> None:
for task in self.tasks:
task.execute(context)
class UserRegistrationFacade:
def __init__(self):
self.executor = TaskExecutor()
self.executor.add_task(LogTask())
self.executor.add_task(NotifyTask())
def register_user(self, user: str) -> None:
context = {"user": user}
self.executor.execute_all(context)
# δ½Ώη¨δΎ
facade = UserRegistrationFacade()
facade.register_user("taro@example.com")
β Explanationβ
UserRegistrationFacade
exposes a simpleregisterUser()
method to clients- Internally, it uses
TaskExecutor
to iterate through a list of tasks implementing a sharedTask
interface - New tasks (e.g., logging, sending notifications) can be added without modifying the facade logic
This combination provides high cohesion and low coupling, improving reusability, readability, and testability.
β Summaryβ
- Facade offers a simplified interface for complex operations
- Iterator modularizes and sequences operations step-by-step
- Perfect for workflows that need to be simple on the outside but flexible and extensible on the inside