# JavaScript Design Patterns

Design patterns are reusable solutions to common problems in software design. In JavaScript, they are crucial for writing maintainable, scalable, and secure code.

## 1. Module Pattern

The Module Pattern is used to emulate the concept of classes (before ES6) and to handle encapsulation. It keeps variables private and exposes only a public API.

```javascript
const myModule = (function() {
  const privateVar = "I am private";
  
  function privateMethod() {
    console.log(privateVar);
  }

  return {
    publicMethod: function() {
      privateMethod();
    }
  };
})();

myModule.publicMethod(); // "I am private"
// myModule.privateMethod(); // Error
```

## 2. Singleton Pattern

The Singleton Pattern ensures that a class has only one instance and provides a global point of access to it.

```javascript
const Singleton = (function() {
  let instance;

  function createInstance() {
    const object = new Object("I am the instance");
    return object;
  }

  return {
    getInstance: function() {
      if (!instance) {
        instance = createInstance();
      }
      return instance;
    }
  };
})();

const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();

console.log(instance1 === instance2); // true
```

## 3. Factory Pattern

The Factory Pattern is a creational pattern that provides an interface for creating objects but allows subclasses to alter the type of objects that will be created.

```javascript
class Car {
  constructor(options) {
    this.doors = options.doors || 4;
    this.state = options.state || "brand new";
    this.color = options.color || "silver";
  }
}

class Truck {
  constructor(options) {
    this.state = options.state || "used";
    this.wheelSize = options.wheelSize || "large";
    this.color = options.color || "blue";
  }
}

class VehicleFactory {
  createVehicle(options) {
    if (options.vehicleType === "car") {
      return new Car(options);
    } else if (options.vehicleType === "truck") {
      return new Truck(options);
    }
  }
}
```

## 4. Observer Pattern

The Observer Pattern defines a subscription mechanism to notify multiple objects about any events that happen to the object they're observing.

```javascript
class Subject {
  constructor() {
    this.observers = [];
  }

  subscribe(observer) {
    this.observers.push(observer);
  }

  unsubscribe(observer) {
    this.observers = this.observers.filter(obs => obs !== observer);
  }

  notify(data) {
    this.observers.forEach(observer => observer.update(data));
  }
}

class Observer {
  update(data) {
    console.log("Observer received:", data);
  }
}
```

[[programming/javascript/vanilla/javascript]]
[[programming/design-patterns-index]]