Skip to content

Commit 37f6e60

Browse files
Mayur KadamMayur Kadam
authored andcommitted
Added state design pattern, added removed decorator pattern readme file
1 parent 0f09380 commit 37f6e60

File tree

9 files changed

+359
-0
lines changed

9 files changed

+359
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { TrafficLightState } from "./interface";
2+
3+
export class GreenLight implements TrafficLightState {
4+
getState(): void {
5+
console.log("🚦 Green Light - GO!");
6+
}
7+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# 🚦 Traffic Light System - State Design Pattern
2+
3+
## 📌 Overview
4+
The **State Design Pattern** allows an object to change its behavior when its internal state changes. Instead of using multiple `if-else` conditions, each state is encapsulated into a separate class.
5+
6+
This example demonstrates a **Traffic Light System**, which transitions between different states: **Red**, **Yellow**, and **Green**.
7+
8+
---
9+
10+
## 🛠️ **Implementation Details**
11+
12+
### **1️⃣ State Interface**
13+
The interface defines the `getState()` method that each state must implement.
14+
15+
```typescript
16+
// TrafficLightState.ts
17+
export interface TrafficLightState {
18+
getState(): void;
19+
}
20+
```
21+
22+
### **2️⃣ Concrete States**
23+
Each traffic light state (Red, Yellow, Green) is implemented as a separate class.
24+
25+
```typescript
26+
// RedLight.ts
27+
import { TrafficLightState } from "./TrafficLightState";
28+
29+
export class RedLight implements TrafficLightState {
30+
getState(): void {
31+
console.log("🚦 Red Light - STOP!");
32+
}
33+
}
34+
```
35+
36+
```typescript
37+
// YellowLight.ts
38+
import { TrafficLightState } from "./TrafficLightState";
39+
40+
export class YellowLight implements TrafficLightState {
41+
getState(): void {
42+
console.log("🚦 Yellow Light - GET READY!");
43+
}
44+
}
45+
```
46+
47+
```typescript
48+
// GreenLight.ts
49+
import { TrafficLightState } from "./TrafficLightState";
50+
51+
export class GreenLight implements TrafficLightState {
52+
getState(): void {
53+
console.log("🚦 Green Light - GO!");
54+
}
55+
}
56+
```
57+
58+
### **3️⃣ Context Class (Traffic Light Controller)**
59+
This class maintains the current state and delegates requests to it.
60+
61+
```typescript
62+
// TrafficLight.ts
63+
import { TrafficLightState } from "./TrafficLightState";
64+
65+
export class TrafficLight {
66+
private state: TrafficLightState;
67+
68+
constructor(initialState: TrafficLightState) {
69+
this.state = initialState;
70+
}
71+
72+
setState(state: TrafficLightState): void {
73+
this.state = state;
74+
}
75+
76+
getState(): void {
77+
this.state.getState();
78+
}
79+
}
80+
```
81+
82+
### **4️⃣ Example Usage (Testing the Traffic Light System)**
83+
84+
```typescript
85+
// index.ts
86+
import { TrafficLight } from "./TrafficLight";
87+
import { RedLight } from "./RedLight";
88+
import { YellowLight } from "./YellowLight";
89+
import { GreenLight } from "./GreenLight";
90+
91+
// Initialize with RedLight state
92+
const trafficLight = new TrafficLight(new RedLight());
93+
trafficLight.getState(); // Output: 🚦 Red Light - STOP!
94+
95+
// Change to Yellow Light
96+
trafficLight.setState(new YellowLight());
97+
trafficLight.getState(); // Output: 🚦 Yellow Light - GET READY!
98+
99+
// Change to Green Light
100+
trafficLight.setState(new GreenLight());
101+
trafficLight.getState(); // Output: 🚦 Green Light - GO!
102+
```
103+
104+
---
105+
106+
## 📈 **Benefits of State Design Pattern**
107+
**Encapsulation** - Each state’s logic is encapsulated in separate classes.
108+
**Improves Maintainability** - No long `if-else` conditions.
109+
**Scalability** - Easily add new states without modifying existing logic.
110+
**Better Readability** - Clearer, modular code structure.
111+
112+
---
113+
114+
## 🔥 **Conclusion**
115+
The **State Design Pattern** is useful when an object’s behavior changes based on its state. In this traffic light example, each light state is encapsulated separately, making the system more maintainable and scalable.
116+
117+
---
118+
119+
Would you like additional modifications or a real-world use case example? 🚀
120+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { TrafficLightState } from "./interface";
2+
3+
export class RedLight implements TrafficLightState {
4+
getState(): void {
5+
console.log("🚦 Red Light - STOP!");
6+
}
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { TrafficLightState } from "./interface";
2+
3+
export class TrafficLight {
4+
state: TrafficLightState;
5+
6+
constructor(state: TrafficLightState) {
7+
this.state = state;
8+
}
9+
10+
setState(state: TrafficLightState): void {
11+
this.state = state;
12+
}
13+
14+
getState(){
15+
this.state.getState();
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { TrafficLightState } from "./interface";
2+
3+
export class YellowLight implements TrafficLightState {
4+
getState(): void {
5+
console.log("🚦 Yellow Light - GET READY!");
6+
}
7+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { GreenLight } from "./GreenLight";
2+
import { RedLight } from "./RedLight";
3+
import { TrafficLight } from "./TrafficLight";
4+
import { YellowLight } from "./YellowLight";
5+
6+
// Initialize with RedLight state
7+
const trafficLight = new TrafficLight(new RedLight());
8+
trafficLight.getState(); // Output: 🚦 Red Light - STOP!
9+
10+
// Change to Yellow Light
11+
trafficLight.setState(new YellowLight());
12+
trafficLight.getState(); // Output: 🚦 Yellow Light - GET READY!
13+
14+
// Change to Green Light
15+
trafficLight.setState(new GreenLight());
16+
trafficLight.getState(); // Output: 🚦 Green Light - GO!
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export interface TrafficLightState {
2+
getState(): void;
3+
}
4+
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# Vehicle System - Decorator Design Pattern
2+
3+
## 📌 Introduction
4+
The **Decorator Design Pattern** is a structural pattern that allows us to dynamically add behavior to objects without modifying their existing structure. This pattern follows the **Open/Closed Principle**, making it easy to extend functionalities without altering the original class.
5+
6+
In this repository, we implement the **Decorator Pattern** in a **Vehicle System**, where we can add features like **GPS, Sunroof, and Sports Mode** to a base car dynamically.
7+
8+
---
9+
10+
## 📁 Folder Structure
11+
```
12+
/VehicleSystem
13+
│── index.ts # Entry point for testing the decorators
14+
│── Vehicle.ts # Interface for Vehicle component
15+
│── /Base
16+
│ │── BaseCar.ts # Concrete component (Base Car)
17+
│ │── BaseBike.ts # Concrete component (Base Bike)
18+
│── /Decorators
19+
│ │── VehicleDecorator.ts # Abstract class for decorators
20+
│── GPS.ts # Concrete Decorator - Adds GPS
21+
│── Sunroof.ts # Concrete Decorator - Adds Sunroof
22+
│── SportsMode.ts # Concrete Decorator - Adds Sports Mode
23+
```
24+
25+
## 🎯 Problem Statement
26+
We need a **flexible way to add features to cars & bikes** (such as GPS, Sunroof, and Sports Mode) **without modifying the base class**. Instead of creating multiple subclasses for different feature combinations, we use **Decorators** to dynamically enhance car functionality.
27+
28+
---
29+
30+
## 🏗️ Implementation Details
31+
32+
### **1️⃣ Component Interface (Vehicle)**
33+
Defines the core structure of a vehicle:
34+
```typescript
35+
export interface Vehicle {
36+
getDescription(): string;
37+
getCost(): number;
38+
}
39+
```
40+
41+
### **2️⃣ Concrete Component (Base Car)**
42+
A simple base car with a default description and cost:
43+
```typescript
44+
export class BaseCar implements Vehicle {
45+
getDescription(): string {
46+
return "Base Car";
47+
}
48+
getCost(): number {
49+
return 500000; // Base price
50+
}
51+
}
52+
```
53+
54+
### **3️⃣ Abstract Decorator (VehicleDecorator)**
55+
Wraps the vehicle and allows additional functionality:
56+
```typescript
57+
export class VehicleDecorator implements Vehicle {
58+
decoratedVehicle: Vehicle;
59+
60+
constructor(decoratedVehicle: Vehicle) {
61+
this.decoratedVehicle = decoratedVehicle;
62+
}
63+
64+
getCost(): number {
65+
return this.decoratedVehicle.getCost();
66+
}
67+
getDescription(): string {
68+
return this.decoratedVehicle.getDescription();
69+
}
70+
}
71+
```
72+
73+
### **4️⃣ Concrete Decorators (Adding Features)**
74+
#### 📍 GPS Feature:
75+
```typescript
76+
export class GPS extends CarDecorator {
77+
getDescription(): string {
78+
return `${this.decoratedCar.getDescription()}, GPS`;
79+
}
80+
getCost(): number {
81+
return this.decoratedCar.getCost() + 30000;
82+
}
83+
}
84+
```
85+
#### 📍 Sunroof Feature:
86+
```typescript
87+
export class Sunroof extends VehicleDecorator {
88+
getDescription(): string {
89+
return `${this.decoratedCar.getDescription()}, Sunroof`;
90+
}
91+
getCost(): number {
92+
return this.decoratedCar.getCost() + 50000;
93+
}
94+
}
95+
```
96+
#### 📍 Sports Mode Feature:
97+
```typescript
98+
export class SportsMode extends VehicleDecorator {
99+
getDescription(): string {
100+
return `${this.decoratedCar.getDescription()}, Sports Mode`;
101+
}
102+
getCost(): number {
103+
return this.decoratedCar.getCost() + 70000;
104+
}
105+
}
106+
```
107+
108+
---
109+
110+
## 🚀 Running the Code
111+
The `index.ts` file demonstrates how to apply the decorators dynamically:
112+
```typescript
113+
import { BasicCar } from "./BasicCar";
114+
import { GPS } from "./GPS";
115+
import { Sunroof } from "./Sunroof";
116+
import { SportsMode } from "./SportsMode";
117+
118+
// CAR
119+
let myCar = new BaseCar();
120+
121+
console.log(`${myCar.getDescription()} costs ₹${myCar.getCost()}`);
122+
console.log();
123+
124+
myCar = new GPS(myCar);
125+
console.log(`${myCar.getDescription()} costs ₹${myCar.getCost()}`);
126+
console.log();
127+
128+
myCar = new Sunroof(myCar);
129+
console.log(`${myCar.getDescription()} costs ₹${myCar.getCost()}`);
130+
console.log();
131+
132+
myCar = new SportsMode(myCar);
133+
console.log(`${myCar.getDescription()} costs ₹${myCar.getCost()}`);
134+
console.log();
135+
136+
// BIKE
137+
let myBike = new BaseBike();
138+
139+
console.log(`${myBike.getDescription()} costs ₹${myBike.getCost()}`);
140+
console.log();
141+
142+
myBike = new GPS(myBike);
143+
console.log(`${myBike.getDescription()} costs ₹${myBike.getCost()}`);
144+
console.log();
145+
146+
myBike = new SportsMode(myBike);
147+
console.log(`${myBike.getDescription()} costs ₹${myBike.getCost()}`);
148+
console.log();
149+
```
150+
151+
### **📝 Expected Output**
152+
```
153+
Base Car costs ₹500000
154+
155+
Base Car, GPS costs ₹530000
156+
157+
Base Car, GPS, Sunroof costs ₹580000
158+
159+
Base Car, GPS, Sunroof, Sport Mode. costs ₹650000
160+
161+
Base Bike costs ₹100000
162+
163+
Base Bike, GPS costs ₹130000
164+
165+
Base Bike, GPS, Sport Mode. costs ₹200000
166+
```
167+
168+
---
169+
170+
## 📈 Benefits of Decorator Pattern
171+
**Open/Closed Principle** - Extend functionality without modifying existing code.
172+
**Flexible & Scalable** - Add or remove features dynamically.
173+
**Avoids Subclass Explosion** - No need to create multiple subclasses for different feature combinations.
174+
**Runtime Behavior Modification** - Features can be added at runtime based on requirements.
175+
176+
177+
---
178+
179+
## 🏆 Conclusion
180+
The **Decorator Pattern** is an excellent choice when we need to add new functionalities dynamically without modifying the core structure. It provides a clean and scalable way to enhance objects without subclassing.

readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,4 @@ Understand system design principles and implement design patterns.
168168
| [Abstract Factory (Vehicle System)](./05%20-%20Low%20Level%20Design/03%20-%20TypeScript%20Design%20Pattern/Creational%20Design%20Patterns/Abstract%20Factory/Vehicle%20System/README.md) | [Decorator Pattern (Vehicle System)](./05%20-%20Low%20Level%20Design/03%20-%20TypeScript%20Design%20Pattern/Structural%20Design%20Patterns/Decorator/Vehicle%20System/README.md) | [Chain of Responsibility (Logging System)](./05%20-%20Low%20Level%20Design/03%20-%20TypeScript%20Design%20Pattern/Behavioral%20Design%20Patterns/Chain%20of%20Responsibility/%20Logging%20System/README.md) |
169169
| | [Adapter Pattern (Vehicle Charging System)](./05%20-%20Low%20Level%20Design/03%20-%20TypeScript%20Design%20Pattern/Structural%20Design%20Patterns/Adapter/Vehicle%20Charging%20System/README.md) | [Strategy Pattern (Vehicle System)](./05%20-%20Low%20Level%20Design/03%20-%20TypeScript%20Design%20Pattern/Behavioral%20Design%20Patterns/Strategy%20Pattern/Vehicle%20System/Vehicle%20System%20With%20Strategy%20Pattern/README.md) |
170170
| | | [Observer Pattern (Traffic Signal)](./05%20-%20Low%20Level%20Design/03%20-%20TypeScript%20Design%20Pattern/Behavioral%20Design%20Patterns/Observer%20Pattern/Traffic%20Signal/README.md) |
171+
| | | [State Pattern (Traffic Light System)](./05%20-%20Low%20Level%20Design/03%20-%20TypeScript%20Design%20Pattern/Behavioral%20Design%20Patterns/State/Traffic%20Light%20System/README.md) |

0 commit comments

Comments
 (0)