🧩 Flyweight Pattern
✅ Intent
- Share objects that contain invariant, common data to reduce memory usage
- Extract and externalize varying data (context) while keeping shared logic centralized
✅ Motivation
- Avoid creating numerous nearly identical objects when only a few fields vary
- Consolidate templates, formatting rules, or behavior that is reused across many instances
✅ When to Use
- You need to manage a large number of similar objects
- Only part of each object’s state differs (e.g., label text, position, user ID)
- You want to optimize memory or avoid duplication in UI, graphics, reporting, etc.
✅ Code Example
- TypeScript
- PHP
- Python
// Flyweight(共通部分)
class NotificationTemplate {
constructor(public header: string, public footer: string) {}
format(user: string, body: string): string {
return `${this.header}\n宛先: ${user}\n本文: ${body}\n${this.footer}`;
}
}
// Context(可変部分を持つ)
class Notification {
constructor(
private user: string,
private message: string,
private template: NotificationTemplate
) {}
send() {
console.log(this.template.format(this.user, this.message));
}
}
// 利用例:テンプレートは共有
const sharedTemplate = new NotificationTemplate(
"件名: お知らせ",
"-- 通知システム"
);
new Notification("hiroshi", "メッセージ1", sharedTemplate).send();
new Notification("satoshi", "メッセージ2", sharedTemplate).send();
<?php
class NotificationTemplate {
public function __construct(public string $header, public string $footer) {}
public function format(string $user, string $body): string {
return "{$this->header}\n宛先: {$user}\n本文: {$body}\n{$this->footer}";
}
}
class Notification {
public function __construct(
private string $user,
private string $message,
private NotificationTemplate $template
) {}
public function send(): void {
echo $this->template->format($this->user, $this->message) . "\n";
}
}
// 利用例
$template = new NotificationTemplate("件名: お知らせ", "-- 通知システム");
(new Notification("hiroshi", "メッセージ1", $template))->send();
(new Notification("satoshi", "メッセージ2", $template))->send();
class NotificationTemplate:
def __init__(self, header: str, footer: str):
self.header = header
self.footer = footer
def format(self, user: str, body: str) -> str:
return f"{self.header}\n宛先: {user}\n本文: {body}\n{self.footer}"
class Notification:
def __init__(self, user: str, message: str, template: NotificationTemplate):
self.user = user
self.message = message
self.template = template
def send(self):
print(self.template.format(self.user, self.message))
# 利用例
shared_template = NotificationTemplate("件名: お知らせ", "-- 通知システム")
Notification("hiroshi", "メッセージ1", shared_template).send()
Notification("satoshi", "メッセージ2", shared_template).send()
✅ Explanation
This code uses the Flyweight
pattern to share a common notification template across many instances. Each Notification
only stores dynamic context, like user or message content.
The flyweight stores the static structure (header
, footer
, etc.), and is reused wherever possible.
1. Flyweight Pattern Overview
-
Flyweight: Shared object containing immutable data
→NotificationTemplate
-
Context: Stores varying state and uses the Flyweight object
→Notification
-
Client: Creates many
Notification
instances reusing the sameNotificationTemplate
2. Key Classes and Responsibilities
-
NotificationTemplate
- Holds common, reusable message format logic
- Formats full message from a header, content, and footer
-
Notification
- Holds contextual, variable data (e.g., user and message)
- Delegates formatting to the shared
NotificationTemplate
-
Client Code
- Shares a single instance of
NotificationTemplate
and uses it to send many personalized notifications
- Shares a single instance of
3. UML Class Diagram
4. Benefits of the Flyweight Pattern
- Reduced memory usage: Share large, constant structures across instances
- Simplified logic: Common formatting or display logic is centralized
- High performance: Especially useful when working with UIs, game objects, icons, etc.
This design is ideal when building scalable systems that handle large numbers of small objects with repeated structure—particularly in UI, graphics, or reporting layers.