flyweight-pattern
Teaches the flyweight pattern for memory optimization. Use when your application creates large numbers of similar objects and memory consumption is a concern.
What this skill does
# Flyweight Pattern
The flyweight pattern is a useful way to conserve memory when we're creating a large number of similar objects.
In our application, we want users to be able to add books. All books have a `title`, an `author`, and an `isbn` number! However, a library usually doesn't have just one copy of a book: it usually has multiple copies of the same book.
## When to Use
- Use this when creating a huge number of objects that could potentially drain available memory
- This is helpful when many objects share the same intrinsic properties (e.g., books with the same ISBN)
## When NOT to Use
- When the number of objects is small enough that memory is not a concern
- When objects have few or no shared intrinsic properties — the separation of intrinsic and extrinsic state adds complexity without savings
- When the added lookup/management overhead outweighs the memory benefit
## Instructions
- Separate intrinsic (shared) state from extrinsic (unique) state
- Use a Map or similar structure to cache and reuse shared object instances
- Consider JavaScript's prototypal inheritance as a simpler alternative in many cases
## Details
It wouldn't be very useful to create a new book instance each time if there are multiple copies of the exact same book. Instead, we want to create multiple instances of the `Book` constructor, that represent a single book.
```js
class Book {
constructor(title, author, isbn) {
this.title = title;
this.author = author;
this.isbn = isbn;
}
}
```
Let's create the functionality to add new books to the list. If a book has the same ISBN number, thus is the exact same book type, we don't want to create an entirely new `Book` instance. Instead, we should first check whether this book already exists.
```js
const books = new Map();
const createBook = (title, author, isbn) => {
const existingBook = books.has(isbn);
if (existingBook) {
return books.get(isbn);
}
};
```
If it doesn't contain the book's ISBN number yet, we'll create a new book and add its ISBN number to the `isbnNumbers` set.
```js
const createBook = (title, author, isbn) => {
const existingBook = books.has(isbn);
if (existingBook) {
return books.get(isbn);
}
const book = new Book(title, author, isbn);
books.set(isbn, book);
return book;
};
```
The `createBook` function helps us create new instances of one type of book. However, a library usually contains multiple copies of the same book! Let's create an `addBook` function, which allows us to add multiple copies of the same book. It should invoke the `createBook` function, which returns either a newly created `Book` instance, or returns the already existing instance.
In order to keep track of the total amount of copies, let's create a `bookList` array that contains the total amount of books in the library.
```js
const bookList = [];
const addBook = (title, author, isbn, availability, sales) => {
const book = {
...createBook(title, author, isbn),
sales,
availability,
isbn,
};
bookList.push(book);
return book;
};
```
Perfect! Instead of creating a new `Book` instance each time we add a copy, we can effectively use the already existing `Book` instance for that particular copy. Let's create 5 copies of 3 books: Harry Potter, To Kill a Mockingbird, and The Great Gatsby.
```js
addBook("Harry Potter", "JK Rowling", "AB123", false, 100);
addBook("Harry Potter", "JK Rowling", "AB123", true, 50);
addBook("To Kill a Mockingbird", "Harper Lee", "CD345", true, 10);
addBook("To Kill a Mockingbird", "Harper Lee", "CD345", false, 20);
addBook("The Great Gatsby", "F. Scott Fitzgerald", "EF567", false, 20);
```
Although there are 5 copies, we only have 3 `Book` instances!
The flyweight pattern is useful when you're creating a huge number of objects, which could potentially drain all available RAM. It allows us to minimize the amount of consumed memory.
In JavaScript, we can easily solve this problem through [prototypal inheritance](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain). Nowadays, hardware has GBs of RAM, which makes the flyweight pattern less important.
## Source
- [patterns.dev/vanilla/flyweight-pattern](https://patterns.dev/vanilla/flyweight-pattern)
### References
- [Flyweight](https://refactoring.guru/design-patterns/flyweight) - Refactoring Guru
- [Flyweight Design Pattern](https://howtodoinjava.com/design-patterns/structural/flyweight-design-pattern) - How To Do In Java
Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.