Object Orinted Programming
Singleton Pattern
- Unique instance: A class can only create one instance
- Global accessable: through static method or variable
- Delayed initialization: Instance are created at first invocation
class Singleton {
constructor() {
if (Singleton.instance) {
return Singleton.instance
}
Singleton.instance = this
}
showMessage() {
console.log("This is a singleton!")
}
}
Factory Pattern
- Create objects via factory methods, instead
new
operator - Specified class instance depends on child class methods
class Product {
constructor (name) {
this.name = name
}
}
class ProductFactory {
static createProduct(type) {
if (type === 'A') {
return new Product("Product A")
} else if (type === 'B') {
return new Product("Product B")
} else {
throw new Error("Unknown product type")
}
}
}
const productA = ProductFactory.createProduct("A")
console.log(productA.name) // Product A
Observer Pattern
- Define object 1 vs N dependency relations
- notify all observers and update when object status changes
class Observer {
update(date) {
console.log("Observer received:", data)
}
}
class Subject {
constructor() {
this.observers = []
}
add(observer) {
this.observers.push(observer)
}
notify(data) {
this.observers.forEach((obs) => obs.update(data))
}
}
const subject = new Subject()
const obs1 = new Observer()
const obs2 = new Observer()
subject.add(obs1)
subject.add(obs2)
subject.notify("Hello Ya!")
Strategy Pattern
- Predefine a series of algorithms, isolated strategy class are interchangeable
- Avoid using massive
if-else
orswitch
statement
class StrategyA {
exec() {
console.log("Strategy A executed")
}
}
class StrategyB {
exec() {
console.log("Strategy B executed")
}
}
class Context {
set(strategy) {
this.strategy = strategy
}
exec() {
this.strategy.exec()
}
}
const ctx = new Context()
ctx.set(new StrategyA())
ctx.exec()
ctx.set(new StrategyB())
ctx.exec()
Proxy pattern
- Add extra layer of process
- Control object access as a proxy
class RealSubject {
request() {
console.log("RealSubject: Handling request")
}
}
class Proxy {
constructor(realSubject) {
this.realSubject = realSubject
}
request() {
console.log("Proxy: Logging access.")
this.realSubject.request()
}
}
const rs = new ReadSubject()
const p = new Proxy(rs)
p.request()
// Proxy: Logging access.
// RealSubject: Handling request
Decorator Pattern
- Add new functionality dynamically, does not affect other objects
- extends class functionalities instead creating child classes
class Coffee {
cost() {
return 5
}
}
class MilkDecorator {
constructor(coffee) {
this.coffee = coffee
}
cost() {
return this.coffee.cost() + 2
}
}
class SugarDecorator {
constructor(coffee) {
this.coffee = coffee
}
cost() {
return this.coffee.cost() + 1
}
}
let coffee = new Coffee()
coffee = new MilkDecorator(coffee)
coffee = new SugarDecorator(coffee)
console.log(coffee.cost())
// 8
Page Source