Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/Structural/Flyweight/ExampleFlyweight.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
type Flyweight = {
color: string;
size: number;
};

class ShapeFlyweightFactory {
private flyweights: { [key: string]: Flyweight } = {};

getFlyweight(color: string, size: number): Flyweight {
const key = `${color}-${size}`;
if (!this.flyweights[key]) {
this.flyweights[key] = { color, size };
}
return this.flyweights[key];
}
}

const shapeFlyweightFactory = new ShapeFlyweightFactory();
63 changes: 63 additions & 0 deletions src/Structural/Flyweight/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@

# Flyweight Design Pattern in React

## Introduction

The **Flyweight** design pattern is one of the structural design patterns that aims to minimize memory usage by sharing as much data as possible with similar objects. This pattern is especially useful in scenarios where applications need to handle a large number of objects that share common properties.

## Why Use the Flyweight Pattern?

### Memory Efficiency
In applications where many objects share similar states, creating individual instances for each object can lead to excessive memory consumption. The Flyweight pattern addresses this issue by enabling the sharing of common data among these objects. By storing shared data in a central location and referencing it, the Flyweight pattern reduces the overall memory footprint.

### Performance Improvement
Reducing memory usage directly translates to performance gains. With less memory consumption, the system experiences fewer cache misses, reduced garbage collection overhead, and generally faster access to data. This makes the application more responsive and capable of handling larger workloads efficiently.

### Simplified Object Management
The Flyweight pattern promotes centralized management of shared data, making the system easier to maintain. Changes to the shared state only need to be made in one place, reducing the risk of inconsistencies and bugs. This centralized management also makes the codebase cleaner and more comprehensible.

## When to Use the Flyweight Pattern?

### Large Number of Similar Objects
The Flyweight pattern is ideal for applications that need to create and manage a large number of similar objects. Examples include graphical applications that render many instances of the same shape, text editors that handle many characters, or game development where multiple similar entities exist.

### High Memory Overhead
When the memory overhead of creating many instances of similar objects becomes significant, the Flyweight pattern can help mitigate this by sharing common state among objects. This is particularly important in environments with limited memory resources, such as mobile devices or embedded systems.

### Shared Significant Data
The pattern is most effective when the objects share a significant amount of data. For instance, in a text editor, individual character objects might share font information, color, and other stylistic attributes. By sharing this data, the Flyweight pattern can reduce the amount of redundant information stored in memory.

## Detailed Explanation

### Concept of Intrinsic and Extrinsic State

The Flyweight pattern divides the state of an object into intrinsic and extrinsic states:

- **Intrinsic State**: This is the state that is shared among multiple objects. It is independent of the object's context and remains constant across different instances. In the context of React, intrinsic state can include properties like shape dimensions, colors, and styles that are common among many components.

- **Extrinsic State**: This is the state that is unique to each object and cannot be shared. It depends on the context in which the object is used. In a React application, extrinsic state can include properties like the position of a component on the screen or user-specific data.

### Flyweight Factory

The Flyweight pattern employs a factory to manage the shared objects (flyweights). This factory is responsible for creating and managing the flyweights, ensuring that new objects are only created when necessary. When an object with a given intrinsic state is requested, the factory either returns an existing flyweight or creates a new one if it does not already exist.

### Practical Example in React

Consider a React application that renders a large number of circles with different colors and sizes. Without the Flyweight pattern, each circle would be an individual component with its own state, leading to high memory usage. By implementing the Flyweight pattern, we can share the color and size data among the circles, significantly reducing the memory footprint.

In this scenario:

- **Intrinsic State**: The color and size of the circles. This state is shared among many circle components.
- **Extrinsic State**: The position of each circle on the screen. This state is unique to each circle component.

By using a Flyweight factory, we can manage the intrinsic state efficiently and ensure that each unique combination of color and size is created only once and shared among all circles that need it.

### Benefits of Using Flyweight in React

1. **Improved Performance**: By sharing common state, React applications can render large numbers of components more efficiently, reducing the time and memory required for rendering.

2. **Reduced Memory Usage**: The Flyweight pattern minimizes the memory required to store state, allowing applications to scale more effectively.

3. **Cleaner Codebase**: Centralized management of shared state simplifies the code, making it easier to understand and maintain.

4. **Enhanced Maintainability**: Changes to shared properties are made in a single place, reducing the risk of inconsistencies and simplifying updates.
21 changes: 21 additions & 0 deletions src/Structural/Flyweight/ShapeComponents.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from "react";

interface ShapeProps {
flyweight: Flyweight;
position: { x: number; y: number };
}

const Shape: React.FC<ShapeProps> = ({ flyweight, position }) => {
const style: React.CSSProperties = {
backgroundColor: flyweight.color,
width: flyweight.size,
height: flyweight.size,
borderRadius: "50%",
position: "absolute",
left: position.x,
top: position.y,
};
return <div style={style}></div>;
};

export default Shape;
26 changes: 26 additions & 0 deletions src/Structural/Flyweight/main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import ReactDOM from 'react-dom';
import Shape from './Shape';

const App: React.FC = () => {
const shapes: JSX.Element[] = [];
const colors = ['red', 'green', 'blue', 'yellow'];
const sizes = [50, 60, 70, 80];

for (let i = 0; i < 1000; i++) {
const color = colors[Math.floor(Math.random() * colors.length)];
const size = sizes[Math.floor(Math.random() * sizes.length)];
const position = { x: Math.random() * window.innerWidth, y: Math.random() * window.innerHeight };
const flyweight = shapeFlyweightFactory.getFlyweight(color, size);

shapes.push(<Shape key={i} flyweight={flyweight} position={position} />);
}

return (
<div>
{shapes}
</div>
);
};

ReactDOM.render(<App />, document.getElementById('root'));