SOLID principles in JavaScript OOP
SOLID principles in JavaScript OOP
SOLID principles are five fundamental rules that help build readable, extensible, and testable programs using object-oriented approaches. Although JavaScript is a dynamic language, these principles are applicable here as well.
The acronym consists of five principles:
Each class or function should have only one responsibility.
class User { constructor(name) { this.name = name; } }
class UserPrinter { print(user) { console.log(User: ${user.name}); } }
Benefits:
Code should be open for extension but closed for modification.
class Shape { area() { throw new Error('area() not implemented'); } }
class Circle extends Shape { constructor(radius) { super(); this.radius = radius; }
area() { return Math.PI * this.radius ** 2; } }
function printArea(shape) { console.log(shape.area()); }
Benefits:
When class A inherits from class B, objects of A should be able to replace B without causing errors.
class Bird { fly() { console.log('Flying'); } }
class Penguin extends Bird { fly() { throw new Error('Penguins cannot fly'); } }
Here Penguin
violates LSP. Solution: restructure the hierarchy:
class Bird {}
class FlyingBird extends Bird { fly() { console.log('Flying'); } }
class Penguin extends Bird { swim() { console.log('Swimming'); } }
Benefits:
Objects shouldn't be forced to implement functions they don't use.
In JavaScript, this can be understood as: don't create large classes with many unrelated methods.
class MultiFunctionPrinter { print() {} scan() {} fax() {} }
class SimplePrinter { print() {} // scan(), fax() not needed }
Better approach with smaller interfaces:
class Printer { print() {} }
class Scanner { scan() {} }
Benefits:
Modules shouldn't depend on concrete implementations but on abstractions.
class MySQLDatabase { save(data) { console.log(`Saving ${data} to MySQL`); } }
class UserService { constructor(database) { this.database = database; }
saveUser(user) { this.database.save(user); } }
const db = new MySQLDatabase(); const service = new UserService(db); service.saveUser('John');
Here UserService
works with an abstraction of MySQLDatabase
. If we decide to use MongoDB
tomorrow, we only need to change the instance type.
Benefits:
SOLID principles in JavaScript help create clean, extensible, and maintainable code. By applying them, we can design a codebase that withstands changes without breaking.
In the next part, we'll examine Module Pattern and Reveal Pattern in JavaScript - modular structures used in the OOP world.